在我们的测试实验室设置中,我们有两台主机,它们都充当服务器/客户端,因为它们彼此发送心跳。
我正在进行自动化性能测试,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)
有没有人知道这可能是什么?有什么建议?
答案 0 :(得分:0)
在套接字数据传输中,您可以将数据大小预先添加到传输数据中(例如: - 为数据长度保留10个字节),如果您在客户端这样做,则可以获得大小数据接收,等待(循环)和收集完整数据。我以为我可以解决你的问题
答案 1 :(得分:0)
好的,经过几天的调查,我终于找到了它的底部。
我的应用程序创建了一个ServerSocket
,用于侦听传入的连接。但是,外部应用程序的逻辑是错误的,所以它曾经非常重复/经常连接到我的应用程序,导致大量的Socket
对象分配。最后,连接将被关闭,Socket
将被标记为收集。
谜题的第二部分是GC
从未被触发过。如果我有12K Socket
,那么其中只有10-20个“GC
root可达”,而其他则是“无法访问”。如果我强行GC
,那么所有这些都会被清除。由于最多500M消耗了20-30M(由-Xmx
设置),我认为这是GC
从未被触发的原因。
我知道这个答案并不是特别有用,但无论如何我都把它放在这里。对某人有帮助..