我正在寻找应用程序中的内存错误,它似乎与ServerSocketChannel.accept()生成的byte []缓冲区有关。据jvisualvm称,在应用程序使用的505个兆中,byte []数组正在使用90%以上的内存。进一步跟踪,有68k +个byte []实例,到目前为止,最常见的大小是16681。
我已经对这些字节数组进行了随机采样,它们都无一例外地与InputRecord或OutputRecord相关。如果我遵循所有参考,就找不到无法导致Finalizer的东西,以我有限的理解,这意味着该对象已准备好被垃圾回收,但是由于某种原因或其他原因而没有。
我希望我可以附上jvisualvm输出的屏幕截图。无论如何,引用对象包括:
输入记录
AppInputStream
SSLSocketImpl
SocketInputStream
SocksSocketImpl
SocketOutputStream
AppOutputStream
DelegateHttpsURLConnection
HttpsURLConnectionImpl
使用Apple VM的客户似乎只会发生这种情况。有人知道为什么这些缓冲区没有得到垃圾回收吗?我读的堆配置文件有误吗?破解或解决方法?
最佳答案
在垃圾收集器发现对象之后的某个时间调用finalize
。 Sun实现与java.lang.ref
混合在一起。正确关闭资源应释放其内存。如果具有finalize
的对象在关闭时未能使对缓冲区的引用无效,则这些缓冲区将一直徘徊,直到终结器执行后相关的GC。
尽管规范允许很多,但通常只有一个终结器线程。如果由于阻塞操作,不适当的保持锁或其他原因而阻塞了该对象,则将保留可终结对象的GC。我建议检查visualvm中的终结器线程以查看是否被阻止。