我正在探索Java中的内存使用,以了解我的程序泄漏内存的原因。在我的main while循环中剥离代码之后,我仍然会随着时间的推移增加内存使用量。思考空程序的内存使用情况:
class Nothing
{ public static void main(String[] args)
{ while(true); }
}
我仍然看到内存增加:
所以我的问题是:为什么还有锯齿形?为什么GC运行时不会保存所有内存(每次gc运行(山谷),使用的内存增加10-20Kb(与之前的山谷相比))?
修改
java版“1.6.0_29”
Java(TM)SE运行时环境(版本1.6.0_29-b11)
Java HotSpot(TM)客户端VM(版本20.4-b02,混合模式,共享)
操作系统:Windows 7 Enterprise-32位
答案 0 :(得分:11)
为什么还有锯齿形?
如果我没有弄错,部分原因是监视器本身正在强制应用程序创建临时对象,其中包含有关垃圾收集和内存使用状态的信息。
为什么GC运行时不会保存所有内存(每次gc运行(山谷),使用的内存增加10-20Kb(与之前的山谷相比))?
我相信监视器在垃圾收集后不会立即看到已用内存的数量,而是必须经常轮询以查看内存使用情况。因此,感知的“山谷”必然略高于真正的山谷。我会猜测在山谷中内存使用量的感知增加只是这种差异的随机误差,并且会随着时间的推移而中和。 (也就是说,我认为在每个周期中实际上并没有发生10-20 KB的内存泄漏。)
答案 1 :(得分:4)
这是分析器的工件,没有分析器,就不会有分配。不同的剖析器会根据记录数据的方式产生不同的工件。您可以在下面看到JProfiler的概要分析Nothing
:
少得多的锯齿模式。但是,内存消耗也很小:
这是由于分析代理轮询java.lang.management.MemoryUsage
JMX bean。最终这种消费也将触发垃圾收集。