【问题标题】:Java server socket buffers not being garbage collected on MacJava 服务器套接字缓冲区没有在 Mac 上被垃圾收集
【发布时间】:2010-10-26 08:12:38
【问题描述】:

我正在寻找应用程序中的内存错误,它似乎与 ServerSocketChannel.accept() 生成的 byte[] 缓冲区有关。根据 jvisualvm,在应用程序使用的 505 megs 中,超过 90% 的内存被 byte[] 数组使用。进一步跟踪,有 68k+ 个 byte[] 实例,到目前为止最常见的大小是 16681。

我对这些字节数组进行了随机抽样,它们无一例外都与 InputRecord 或 OutputRecord 相关。如果我遵循所有引用,我找不到任何不返回终结器的内容,在我有限的理解中,这意味着该对象已准备好进行垃圾收集,但由于某种原因它还没有.

我希望我可以附上 jvisualvm 输出的屏幕截图。无论如何,所指对象包括:

  • 输入记录
  • AppInputStream
  • SSLSocketImpl
  • SocketInputStream
  • SocksSocketImpl
  • SocketOutputStream
  • AppOutputStream
  • DelegateHttpsURLConnection
  • HttpsURLConnectionImpl

这似乎只发生在使用 Apple 虚拟机的客户身上。有人知道为什么这些缓冲区没有被垃圾收集吗?我读错了堆配置文件吗?黑客或变通方法?

【问题讨论】:

  • 我假设您在这些或相关对象上调用了 close() ?如果你在 VisualVM 中要求 GC,它是否减少了内存消耗?
  • 有类似的问题。此处描述:stackoverflow.com/questions/14610567/…

标签: java macos sockets memory-leaks


【解决方案1】:

finalize 在垃圾收集器发现对象后的某个时间被调用。 Sun 实现与java.lang.ref 混在一起。正确关闭资源应该释放它们的内存。如果带有finalize 的对象在关闭时未能清空对缓冲区的引用,那么这些缓冲区将一直挂起,直到终结器执行后相关的 GC。

通常只有一个终结器线程,尽管规范允许很多。如果由于阻塞操作、不适当的持有锁或其他原因而被阻塞,则可终结对象的 GC 将被搁置。我建议检查visualvm中的finaliser线程,看看它是否被阻塞。

【讨论】:

    猜你喜欢
    • 2010-12-23
    • 2021-11-28
    • 1970-01-01
    • 2013-10-18
    • 2013-05-25
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多