如何清除与 Java 相关的本机内存。我知道 GC 不会清除它
How does Native memory related to Java gets cleared. I understand the GC doesnot clears it
似乎当有 IO 操作等待外部服务时,许多线程正在等待 sun.misc.Unsafe.park。
这导致未清除的本机内存累积。
这个本机内存如何被清除。一段时间后会自动清除吗
使用每连接线程 IO 会产生以下内存成本:
- 线程堆栈
ByteBuffer
或 byte[]
传递给 read/write/send/receive 方法
- 可能是一个反弹缓冲区(一个 openjdk 实现细节),因为系统调用需要一个固定的缓冲区,而 java 数据结构可以被 GC 移动
- 在 IO 函数之上的其他抽象和应用程序在连接的生命周期内保持活动状态
- 内核套接字内存
- 可以通过调整
-Xss
参数来稍微调整一下。一个完整的修复需要通过 nonblocking/asynchronous IO 在更少的线程上多路复用多个连接。 AsynchronousSocketChannel
使它易于用于 TCP 套接字,HttpClient
用于 HTTP。对于其他协议,您需要寻找实现异步 IO 的库。
- 是不可避免的,但根据应用程序设计,可能会有优化空间。例如如果你要发送一个 1GB 的文件,你不需要 1GB 的缓冲区,你可以用较小的缓冲区逐块读取它
- 可以通过将
DirectByteBuffer
实例传递给 IO 方法来避免。使用异步 IO 还减少了需要同时使用的缓冲区总数
- 不特定于 IO,因此适用一般内存占用优化建议
- 通常应该不是问题,因为内核会自动调整它们的大小。但当然,保持数千个套接字打开的时间超过必要时间仍然会产生影响
总的来说,JVM 最终应该清理 IO 所需的本机资源,但何时发生可能取决于您将依赖于这些本机资源的 java 对象保持活动状态的时间。
似乎当有 IO 操作等待外部服务时,许多线程正在等待 sun.misc.Unsafe.park。 这导致未清除的本机内存累积。 这个本机内存如何被清除。一段时间后会自动清除吗
使用每连接线程 IO 会产生以下内存成本:
- 线程堆栈
ByteBuffer
或byte[]
传递给 read/write/send/receive 方法- 可能是一个反弹缓冲区(一个 openjdk 实现细节),因为系统调用需要一个固定的缓冲区,而 java 数据结构可以被 GC 移动
- 在 IO 函数之上的其他抽象和应用程序在连接的生命周期内保持活动状态
- 内核套接字内存
- 可以通过调整
-Xss
参数来稍微调整一下。一个完整的修复需要通过 nonblocking/asynchronous IO 在更少的线程上多路复用多个连接。AsynchronousSocketChannel
使它易于用于 TCP 套接字,HttpClient
用于 HTTP。对于其他协议,您需要寻找实现异步 IO 的库。 - 是不可避免的,但根据应用程序设计,可能会有优化空间。例如如果你要发送一个 1GB 的文件,你不需要 1GB 的缓冲区,你可以用较小的缓冲区逐块读取它
- 可以通过将
DirectByteBuffer
实例传递给 IO 方法来避免。使用异步 IO 还减少了需要同时使用的缓冲区总数 - 不特定于 IO,因此适用一般内存占用优化建议
- 通常应该不是问题,因为内核会自动调整它们的大小。但当然,保持数千个套接字打开的时间超过必要时间仍然会产生影响
总的来说,JVM 最终应该清理 IO 所需的本机资源,但何时发生可能取决于您将依赖于这些本机资源的 java 对象保持活动状态的时间。