Java 服务器套接字缓冲区在 Mac 上没有被垃圾收集

标签 java macos sockets memory-leaks

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

我对这些字节数组进行了随机采样,它们无一异常(exception)都与 InputRecord 或 OutputRecord 相关。如果我遵循所有引用,我找不到任何不返回终结器的引用,以我有限的理解,这意味着该对象已准备好被垃圾收集,但由于某种原因或其他原因尚未准备好.

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

  • 输入记录
  • 应用程序输入流
  • SSLSocketImpl
  • SocketInputStream
  • SocksSocketImpl
  • SocketOutputStream
  • AppOutputStream
  • 委托(delegate)HttpsURLConnection
  • HttpsURLConnectionImpl

这似乎只发生在使用 Apple VM 的客户身上。有人知道为什么这些缓冲区没有被垃圾收集吗?我读取的堆配置文件是否错误?黑客攻击还是解决方法?

最佳答案

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

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

关于Java 服务器套接字缓冲区在 Mac 上没有被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/865951/

相关文章:

java - 尝试 Catch 或 boolean 检查

java - 选择文件的简单方法

cocoa - 使用 Cocoa 绑定(bind)时如何取消保存首选项?

macos - 在 OS X 上禁用 Jenkins 自动启动

cocoa - 在 NSFontPanel 中选择字体

perl - 如何使用 IO::Select 阻止等待读取或写入套接字?

java - Java 和 Python 之间的套接字连接 - struct.unpack 错误

java - spring-oauth2 登录成功处理器

java - 用Java读取目录中文件的扩展名?

sockets - IPv6 范围 ID 与 IPv4