在我们的测试实验室设置中,我们有两个主机,它们都充当服务器/客户端,相互发送检测信号。
我正在运行自动性能测试,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
从未触发的原因。
我知道这个答案不是特别有用,但我还是把它放在这里。可能对某人有所帮助。。