这可能是一个天真的问题。我正在调查我的应用程序中可能的内存泄漏。我一直在通过jvisualvm监控tomcat进程。有一次我选择了堆转储。
我很惊讶地看到我的线程计数,并且在生成堆转储后内存消耗显着下降。参考以下屏幕截图。
为什么我的线程计数和内存因堆转储而丢失?
[编辑]为了回应关于它做出完整垃圾收集以响应堆转储的答案,我的后续问题是,垃圾收集不应该一直发生吗?我没有看到先前的戏剧性下降,只是GC正常发生的常规下降。这个GC循环与正常情况有什么不同?
答案 0 :(得分:2)
在转储之前,您的程序处于稳定状态,包括:
与此同时,周围有很多无法到达的物品,属于终身一代。
然后你做了线程转储。此操作本身会占用大量内存,因此会发生 major 集合。这抹去了你的终身物品。
现在,这些对象可能已经运行了终结器,或者它们可能与某些软引用有关,并且为了响应它们的收集/完成,许多线程已经结束。
这导致堆分配斜率(每秒分配的字节数)变得非常平坦。
答案 1 :(得分:1)
堆转储可能会在写出堆之前触发完整的垃圾收集。
答案 2 :(得分:1)
当您触发堆转储时,您还会触发完整集合。当没有强引用的资源消失时,可以停止一些守护程序线程。