1

这可能是一个幼稚的问题。我正在调查我的应用程序中可能存在的内存泄漏。我一直在通过 jvisualvm 监控 tomcat 进程。有一次,我选择进行堆转储。

我很惊讶地看到我的线程数,并且在生成堆转储后内存消耗大幅下降。参考以下屏幕截图。

线程 记忆

为什么我的线程数和内存仅仅因为堆转储而下降?

[编辑] 为了回应关于它为响应堆转储而进行完整垃圾收集的答案,我的后续问题是,垃圾收集不应该一直发生吗?我没有看到之前的急剧下降,只是在 GC 正常发生时发生的常规下降。这个 GC 周期与正常发生的有什么不同?

4

3 回答 3

2

在转储之前,您的程序处于稳定状态,包括:

  1. 分配短期对象;
  2. 发生次要 GC,将它们全部清除。

与此同时,周围还挂着相当多的遥不可及的物体,属于老生常谈的一代。

然后你做了线程转储。此操作本身会消耗大量内存,因此发生了一次收集。这消灭了你的终身对象。

现在,这些对象可能已经运行了终结器,或者它们可能与一些软引用相关,并且为了响应它们的收集/终结,一些线程结束了。

然后,这会导致您的堆分配斜率(每秒分配的字节数)变得非常平坦。

于 2013-08-01T18:44:17.350 回答
1

堆转储可能会在写出堆之前触发完整的垃圾收集。

于 2013-08-01T18:25:45.247 回答
1

当您触发堆转储时,您也触发了完整的收集。当没有强引用的资源消失时,您的某些守护线程可能会停止。

于 2013-08-01T18:26:41.043 回答