对于大型应用程序,Java 6 消耗的内存是否比您预期的要多?
我有一个已经开发多年的应用程序,到目前为止,在我的特定测试配置中,该应用程序占用了大约 30-40 MB 的空间;现在,对于 Java 6u10 和 11,活动时需要数百个时间。它跳动很多,在 50M 到 200M 之间的任何地方,当它空闲时,它doesGC 并直接删除内存。此外,它还会产生数百万个页面错误。所有这些都可以通过 Windows 任务管理器观察到。
因此,我在我的分析器 (jProfiler) 下运行它并使用 jVisualVM,它们都表明,即使在完全活跃地执行负载测试周期时,通常的中等堆和永久代使用量合计约为 30M。
所以我很迷惑!它不仅仅是从 Windows 虚拟内存池请求更多内存 - 这显示为 200M“内存使用量”。
澄清:我想完全澄清这一点 - 在 Java VisualVM 的 18 小时内观察到,类堆和永久代堆一直非常稳定。分配的易失性堆(eden 和 tenured)保持在 16MB 不变(在前几分钟就达到了),并且该内存的使用量以完美的模式波动,从 8MB 均匀增长到 16MB,此时 GC 会启动将其降回 8MB。在这 18 小时内,自从我进行压力测试以来,系统一直处于恒定的最大负载下。这种行为是完美 and 始终如一地可重复,在多次运行中可见。唯一的异常是,当这种情况发生时,通过任务管理器观察到的从 Windows 获取的内存在 64MB 到 900+MB 之间波动。
2008-12-18 更新:我已经使用 -Xms16M -Xmx16M 运行程序,没有任何明显的不利影响 - 性能很好,总运行时间大致相同。但短期内内存使用仍达到180M左右的峰值。
2009-01-21 更新:看来答案可能在于线程数 - 请参阅下面我的答案。
编辑:我的意思是字面上数百万个页面错误 - 在 30M+ 的区域。
编辑:我有一台4G机器,所以200M在这方面并不重要。
为了回应 Ran 答案评论中的讨论,这里有一个测试用例,证明 JVMwill在某些情况下将内存释放回操作系统:
public class FreeTest
{
public static void main(String[] args) throws Exception
{
byte[][] blob = new byte[60][1024*1024];
for(int i=0; i<blob.length; i++)
{
Thread.sleep(500);
System.out.println("freeing block "+i);
blob[i] = null;
System.gc();
}
}
}
我发现,在 Java 1.4 和 Java 6 JVM(来自 Sun)上,当计数达到 40 左右时,JVM 进程的大小就会减小。
您甚至可以使用以下命令调整确切的行为-XX:MaxHeapFreeRatio 和 -XX:MinHeapFreeRatio 选项 http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#PerformanceTuning-- 该页面上的一些选项也可能有助于回答原始问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)