我有一个Java应用程序,等待用户按键然后运行任务。完成后,它会返回并再次等待。我正在使用jvisualvm查看此应用程序的内存配置文件,它显示了一种不断增加的模式。
提交的内存大小为16MB。 应用程序启动时使用的内存为2.7 MB,然后使用中间丢弃(垃圾收集)进行爬升。一旦这个锯齿模式接近16MB,就会出现大幅下降,内存使用量接近4 MB。然而,这个主要的下降点一直在增加。 4MB,6MB,8MB。使用率从未超过16 MB,但整个锯齿模式正朝着16 MB的方向攀升。
我是否有内存泄漏?
由于这是我第一次发布到StackOverflow,因此没有足够的声誉来发布图片。
答案 0 :(得分:2)
通常会观察到这种锯齿状图案,并不表示内存泄漏。
因为大块垃圾收集比不断收集少量垃圾更有效,JVM会批量收集。这就是你看到这种模式的原因。
答案 1 :(得分:2)
现代SunOracle JVM使用所谓的分代垃圾收集器:
所以基本上,你的程序中的一些东西会长时间被快速的'部分'集合所遗漏,这种情况将会持续到JVM决定它必须进行完整的集合。如果你让它走得足够长,你应该最终看到完整的收集发生并且使用量下降到你原来的起点。
如果这种情况永远不会发生并且你最终得到Out Of Memory异常,那么你可能会有内存泄漏:)
答案 2 :(得分:0)
正如其他人所说,这种行为是正常的。 This是对垃圾收集过程的一个很好的描述。总而言之,JVM使用世代垃圾收集器。绝大多数物体都是非常短暂的,而那些存活时间更长的物体往往会持续更长时间。知道了这一点,GC将首先检查新一代,以避免不必重复检查不太可能无法访问的旧对象。一段时间后,幸存者搬到了老一辈。这种增加的锯齿正是你所看到的 - 上升的低谷是由于老一代人随着幸存者的移动而变得越来越大。如果你的程序运行得足够长,最终检查新一代将无法释放足够的内存,并且它也必须GC也是老一代。
希望有所帮助。