通过JMX在JVisualVM中查看我的远程应用程序时,我发现在空闲时看到了内存使用情况:
使用堆转储并使用JVisualVM对其进行分析,我看到一大块内存位于几个没有引用的大型int []数组中,通过比较堆转储,我可以看到它们似乎正在占用内存和由GC定期收回.
我很想跟踪这些,因为它引起了我的兴趣,我自己的代码永远不会故意分配任何int []数组.
我确实使用了很多像netty这样的库,所以罪魁祸首可能在其他地方.我确实有其他服务器具有相同的框架组合,但在那里看不到这个锯齿.
我怎样才能发现谁在分配它们?
解决方法
获取一个堆转储并找出哪些对象持有它们.一旦你知道什么对象持有阵列,你应该有一个简单的时间想法找出分配它们的内容.
它没有回答你的问题,但我的问题是:
你为什么在乎?
你已经告诉jvm垃圾收集器(GC)它可以使用高达1GB的内存. Java的使用量不到250M.
GC尝试了解垃圾收集的时间以及它在垃圾收集中的工作方式.在图表中,没有内存需求. jvm并不接近你设置的1GB限制.我认为GC没有理由应该非常努力.不确定为什么你会关心.
垃圾收集器懒惰是件好事. GC工作越少,您的应用程序可用的资源就越多.
您是否尝试通过JVisualVM“执行GC”按钮触发GC?该按钮应该触发“停止世界”垃圾收集操作.当图形位于其中一个锯齿斜坡的中间时尝试它 – 我预测使用量将下降到锯齿底部或以下.如果是这样,那证明记忆锯只是垃圾堆积而GC正在做正确的事情.
以下是我使用的java swing应用程序的内存使用情况的屏幕截图:
注意锯齿形图案.
你说你担心int [].当我启动内存分析器并让它描述一切时,我可以看到int []的分配
基本上所有分配都来自ObjectOutputStream $HandleTable.growEntries方法.它看起来像分配的线程被旋转以处理网络消息.我怀疑它是由jmx本身引起的.可能是rmi(你用rmi吗?).或调试器(您是否连接了调试器?).