【问题标题】:How does Native memory related to Java gets cleared. I understand the GC doesnot clears it与 Java 相关的本机内存如何被清除。我了解 GC 不会清除它
【发布时间】:2020-01-16 09:34:57
【问题描述】:

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

【问题讨论】:

  • Unsafe.park 不会增加本机内存占用。请澄清您的意思,最好使用代码示例和诊断工具的输出。
  • Direct ByteBuffers 注册一个Cleaner 对象,该对象在 ByteBuffer 变得无法访问时释放相关的本机内存。
  • 有这个:stackoverflow.com/questions/30458195/… 虽然那是几年前的事了(Java 8 时间框架),但 IIRC 更高版本的 Java 有一些改进

标签: java memory-management jvm heap-memory native


【解决方案1】:

使用 thread-per-connction IO 会产生以下内存成本:

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

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

总体而言,JVM 最终应该清理 IO 所需的本机资源,但何时发生这种情况可能取决于您将依赖于这些本机资源的 java 对象保持多长时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 2022-08-09
    • 2021-07-08
    • 1970-01-01
    相关资源
    最近更新 更多