Java Socket / SocksSocketImpl内存堵塞

时间:2015-04-29 16:05:49

标签: java sockets memory-leaks

在我们的测试实验室设置中,我们有两台主机,它们都充当服务器/客户端,因为它们彼此发送心跳。

我正在进行自动化性能测试,5天后,第一次应用程序的RAM消耗增加稳定但一致。由于测试没有目标心跳应用程序,因此不会出现这种情况。

收集有问题的主机的堆转储并将其加载到MemoryAnalyzer后,我发现了许多“无法访问的”SocksSocketImpl对象。 数量巨大,超过12K的物体。

现在,应用程序确实创建并使用了套接字,但在查看代码后,我非常有信心,那里没有某种创建循环。但是,当应用程序退出时,套接字未正确关闭,但同样,心跳应用程序在这5天内没有重新启动。

我在SO问题中读过这个问题:Memory leak with SocksSocketImpl finalize method

...但是,我正在运行版本1.7.0_76,那里的人写道,该错误已在1.7.0_51修复。

java -version输出:

java version "1.7.0_76"
Java(TM) SE Runtime Environment (build 1.7.0_76-b13)
Java HotSpot(TM) Server VM (build 24.76-b04, mixed mode)

有没有人知道这可能是什么?有什么建议?

2 个答案:

答案 0 :(得分:0)

在套接字数据传输中,您可以将数据大小预先添加到传输数据中(例如: - 为数据长度保留10个字节),如果您在客户端这样做,则可以获得大小数据接收,等待(循环)和收集完整数据。我以为我可以解决你的问题

答案 1 :(得分:0)

好的,经过几天的调查,我终于找到了它的底部。

我的应用程序创建了一个ServerSocket,用于侦听传入的连接。但是,外部应用程序的逻辑是错误的,所以它曾经非常重复/经常连接到我的应用程序,导致大量的Socket对象分配。最后,连接将被关闭,Socket将被标记为收集。

谜题的第二部分是GC从未被触发过。如果我有12K Socket,那么其中只有10-20个“GC root可达”,而其他则是“无法访问”。如果我强行GC,那么所有这些都会被清除。由于最多500M消耗了20-30M(由-Xmx设置),我认为这是GC从未被触发的原因。

我知道这个答案并不是特别有用,但无论如何我都把它放在这里。对某人有帮助..