我有一个spring启动应用程序。它是一个websocket服务器应用程序,我在其中保存和管理各种数据结构中的活动会话,主要是concurrenthashmap和copyonwritearraylist。现在我正在使用jmeter进行负载测试。
使用jmeter,我在300秒内旋转了1200个ws会话。在我结束测试之前,这些会话保持连接。为了强调更多,我通过运行另一个jmeter示例添加了更多的用户会话。
下面是我观察到的在k8s上运行的服务的内存消耗。
部署/启动服务时,内存消耗大约为165MB
然后我启动jmeter负载测试,它在300秒内创建1200个会话。这就增加了内存,达到了400MB左右,这是显而易见的。
几分钟后(20-30分钟),我结束了测试,这使会话数降为零。但是内存保持在400MB左右。我等了将近30分钟,但没有减少。我还添加了日志来打印各种数据结构对象的大小,这些对象包含与用户会话相关的数据。它们都是零。所以从技术上讲,我应该看到以前级别的内存(165MB)。但在我重新启动服务/应用程序之前,这种情况不会发生。
为了检查内存泄漏,我在本地运行应用程序并通过visualvm进行监视。行为是一样的。如下面的屏幕截图所示,线程中的峰值表示我开始jmeter负载测试的时间。这个尖峰的结尾表示我停止负载测试的时间。但是堆空间没有区别。
那么为什么gc不回收内存呢?我遗漏了什么吗?因为它只是停留在最后一个峰值。例如,如果我在负载测试中添加1500个用户会话,并且内存增长到500MB,它将保持在500MB。恐怕,如果随着时间(天)的推移,k8s上运行的服务将失去记忆。
感谢您提出的改进建议。
暂无答案!
目前还没有任何答案,快来回答吧!