如何清除与 Java 相关的本机内存。我知道 GC 不会清除它

How does Native memory related to Java gets cleared. I understand the GC doesnot clears it

似乎当有 IO 操作等待外部服务时,许多线程正在等待 sun.misc.Unsafe.park。 这导致未清除的本机内存累积。 这个本机内存如何被清除。一段时间后会自动清除吗

使用每连接线程 IO 会产生以下内存成本:

  1. 线程堆栈
  2. ByteBufferbyte[] 传递给 read/write/send/receive 方法
  3. 可能是一个反弹缓冲区(一个 openjdk 实现细节),因为系统调用需要一个固定的缓冲区,而 java 数据结构可以被 GC 移动
  4. 在 IO 函数之上的其他抽象和应用程序在连接的生命周期内保持活动状态
  5. 内核套接字内存

  1. 可以通过调整 -Xss 参数来稍微调整一下。一个完整的修复需要通过 nonblocking/asynchronous IO 在更少的线程上多路复用多个连接。 AsynchronousSocketChannel 使它易于用于 TCP 套接字,HttpClient 用于 HTTP。对于其他协议,您需要寻找实现异步 IO 的库。
  2. 是不可避免的,但根据应用程序设计,可能会有优化空间。例如如果你要发送一个 1GB 的文件,你不需要 1GB 的缓冲区,你可以用较小的缓冲区逐块读取它
  3. 可以通过将 DirectByteBuffer 实例传递给 IO 方法来避免。使用异步 IO 还减少了需要同时使用的缓冲区总数
  4. 不特定于 IO,因此适用一般内存占用优化建议
  5. 通常应该不是问题,因为内核会自动调整它们的大小。但当然,保持数千个套接字打开的时间超过必要时间仍然会产生影响

总的来说,JVM 最终应该清理 IO 所需的本机资源,但何时发生可能取决于您将依赖于这些本机资源的 java 对象保持活动状态的时间。