2

我在 java 中使用 RandomAccessFile。我有内存泄漏问题。我已将代码简化为以下内容:

public static void main(String[] args) throws IOException, InterruptedException
{
    RandomAccessFile r = new RandomAccessFile(new File("test.dat"), "rw");
    r.write(new byte[150000000], 0, 150000000);
    r.getFD().sync();
    r.close();
    r = null;

    while (true) { Thread.sleep(1000); }
}

执行此代码(并为 GC 留出足够的时间)后,报告的应用程序内存使用量略高于 150MB。

我错过了什么?还是应该归咎于 Java?

4

3 回答 3

6

GC 只会使内存在 JVM 中可用。GC 释放的内存不会自动返回给操作系统。JVM 通常非常不愿意将内存返回给 OS,因为它可能很快会再次需要它,而从 OS 获取内存是一项相对昂贵的操作。

要查看正在使用和空闲的堆内存百分比,可以使用Visual VM。如果您希望 JVM 更急切地将内存返回给 OS,您可以使用Oracle JVM 的调优参数,具体来说-XX:MaxHeapFreeRatio-XX:MinHeapFreeRatio

于 2010-11-25T09:47:12.997 回答
2

你如何检查内存使用情况?操作系统报告的使用情况仅表明 java 堆的大小已扩大。您无法知道堆是否为空,或者它是否已满但具有符合 GC 条件的对象。

您应该使用一些与java 相关的工具(例如VisualVM 或jmap)。这将使您更好地指示堆内存状态。使用 VisualVM,您可以手动激活 GC,然后检查堆占用情况以确定是否存在内存泄漏。

于 2010-11-25T09:46:12.377 回答
1

内存只在 GC 运行时回收,GC 只在需要时运行。如果您想查看内存使用量下降,请尝试调用 System.gc()。

顺便说一句:Java 不保证将内存返回给操作系统,而是倾向于在内部增加可用内存。

于 2010-11-25T09:45:53.100 回答