为什么JVM堆持续增长?

10

我编写了一个简单的程序,并使用jconsole.exe监控其堆大小。

public class HeapTest {
    public static void main(String[] args) {
        while(true) {
        }
    }
}

这是结果:enter image description here

我不明白为什么堆大小不断增长。 我的程序中没有使用new()创建任何对象。

我的程序中堆用于什么?

我没有向jconsole.exe添加任何额外的参数;只需双击它,然后按照PID加载java进程。

环境:Windows 7下的Java 1.8.0_25


@SMA - 这可能是由于在JVM中运行的后台线程造成的。它们有自己的开销。当JVM启动时,至少会有4个其他线程与“main”线程一起运行。由于它们的执行,堆可能会稳步增长。 - TheLostMind
1
有人能重现这个问题吗?看起来是一个无法复现的问题。我相信作者已经陷入了这种测量中。 - Andremoniy
1
@Andremoniy - 是的。堆增长速度确实令人怀疑。JIT 很可能会对其进行优化,仅使用一条跳转指令。我不明白为什么 这段 代码会影响堆。 - TheLostMind
1
我可以在OSX中复制它。看起来增长是在Eden空间中,一旦发生GC,内存就会被释放,进程重新开始。这可能是两个GC之间的清理数据。 - Khanna111
1
看起来这是将JConsole附加到正在运行的JVM时的某种开销。JVM和JConsole之间的通信是否会分配一些对象? - ZhekaKozlov
显示剩余7条评论
3个回答

5
这里没有内存泄漏。在OSX中进行了复制。这将是虚拟机正常运行所生成的簿记数据,包括GC的数据。Eden空间增加,一旦发生GC,堆(Eden)使用的内存减少,循环重新开始。
令人困惑的是,程序没有显式地创建任何对象,但JVM会这样做,因此Eden空间逐渐增加直到下一个GC。

0

你可以使用JConsole替代命令jmap监控Java进程,从而找到Java堆大小是固定的。


0

你假设 main() 是唯一的线程,这是一个错误的假设。还有其他线程会分配对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接