Java Socket/SocksSocketImpl内存阻塞



在我们的测试实验室设置中,我们有两个主机,它们都充当服务器/客户端,相互发送检测信号。

我正在运行自动性能测试,5天后,在第一个应用程序上,RAM消耗量稳步但一致地增加。由于测试没有目标检测信号应用程序,因此这是意料之中的事。

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

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

我在SO问题中读到了这一点:SocksSocketImpl finalize方法的内存泄漏

然而,我运行的是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)

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

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

好吧,经过几天的调查,我终于弄清了真相。

我的应用程序创建了一个ServerSocket,用于侦听传入连接。然而,外部应用程序的逻辑是错误的,所以它经常重复/频繁地连接到我的应用程序,导致了大量的Socket对象分配。随着时间的推移,连接将被关闭,Socket将被标记为集合。

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

我知道这个答案不是特别有用,但我还是把它放在这里。可能对某人有所帮助。。

最新更新