Java 6 内存使用过多

标签 java memory-management

对于大型应用程序,Java 6 消耗的内存是否比您预期的要多?

我有一个多年来一直在开发的应用程序,到目前为止,在我的特定测试配置中占用了大约 30-40 MB;现在使用 Java 6u10 和 11,它在 Activity 时需要数百个。它反弹很多,介于 50M 和 200M 之间,当它空闲时,它执行 GC 并立即丢弃内存。此外,它还会产生数百万个页面错误。所有这些都通过 Windows 任务管理器进行观察。

所以,我在我的分析器 (jProfiler) 下运行它并使用 jVisualVM,它们都表明通常的中等堆和 perm-gen 使用量合计约为 30M,即使在我的负载测试周期完全活跃时也是如此。

所以我很困惑!而且它不只是从 Windows 虚拟内存池请求更多内存 - 这显示为 200M“内存使用情况”。

澄清:我想非常清楚这一点 - 在 18 小时内使用 Java VisualVM 观察到,类堆和 perm gen 堆非常稳定。分配的 volatile 堆(eden 和tenured)保持不动,为 16MB(它在最初的几分钟内达到),并且此内存的使用以完美的模式波动,从 8MB 均匀增长到 16MB,此时 GC 启动将其降回 8MB。在这 18 小时内,系统处于恒定的最大负载下,因为我正在运行压力测试。这种行为是完美并且始终可重现的,在多次运行中都可以看到。唯一的异常是,当这发生时,从 Windows 获取的内存,通过任务管理器观察到,从 64MB 到 900+MB 到处波动。

2008-12-18 更新:我已经使用 -Xms16M -Xmx16M 运行程序,没有任何明显的不利影响 - 性能很好,总运行时间大致相同。但内存使用在短期内仍达到 180M 左右的峰值。

2009-01-21 更新:似乎答案可能在于线程数 - 请参阅下面的答案。


编辑:我的意思是字面上的数百万个页面错误 - 在 30M+ 的区域内。

编辑:我有一台 4G 机器,所以 200M 在这方面并不重要。

最佳答案

针对 Ran 的回答的评论中的讨论,这里有一个测试用例,证明 JVM 在某些情况下将内存释放回操作系统:

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 and -XX:MinHeapFreeRatio options 调整确切的行为-- 该页面上的一些选项也可能有助于回答原始问题。

关于Java 6 内存使用过多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/366658/

相关文章:

java - 两个独立 LAN 网络上的计算机之间未发生套接字连接

java - 是否-XX :+UseSerialGC use main thread for GC

objective-c - 自定义 NSObject 类,实例化为 [CustomObj customObjWithData :data]

java - java中什么不是类的instanceof?

像安卓一样的Java语音识别

Java:分配未初始化的内存块?

c++ - 带删除的内存管理

c++ - C/C++ malloc/免费。对多个分配使用一个指针 - 坏主意?

java - 在 run() 方法中使用 return 会发生什么?

java - FreeMarker,WebWork 问题