Java - Runtime.freeMemory()

4

我正在尝试查看Runtime.freeMemory()的使用情况。

文档称它“返回Java虚拟机中可用的空闲内存量”。

我执行了一个简单的程序来测试这个功能。程序如下:

public class Test {

 public static void main(String a[]) throws Exception {
    System.out.println("Total memory: " +Runtime.getRuntime().totalMemory());
    System.out.println("Free memory: " +Runtime.getRuntime().freeMemory());
    Integer intArr[]= new Integer[10000];
    for(int i =0; i<10000;i++){
        intArr[i] = new Integer(i+500);
    }
    System.out.println("Free memory: " +Runtime.getRuntime().freeMemory());
    System.out.println("sample print :"+ intArr[0]);
    System.out.println("sample print :"+ intArr[5000]);
    System.out.println("sample print :"+ intArr[9999]);
 }  
}

输出:

总内存:67108864

可用内存:61822408 < 在分配10000个对象之前 >

可用内存:61822408 < 即使在分配10000个对象之后,大小仍然保持不变。为什么?>

示例打印:500

示例打印:5500

示例打印:10499

由于对象是在堆上创建的,第二次打印的“可用内存”值应该比第一次输出少,对吗?

但它打印相同的值。有人能解释一下为什么会打印相同的值吗?


你需要尝试比10000个整数对象更大的东西才能看到差异。 - CoolBeans
@CoolBeans - 平台和 JVM 依赖性强。在我的机器上运行上述代码(Linux + Sun JVM 1.6_22),会显示可用内存下降。 - Brian Roach
你使用的是哪个操作系统,以及Java的哪个版本?你的代码在我的电脑上表现正常。 - Brian Roach
@Brain - 操作系统:Windows XP,JDK-1.6.0_05。感谢您的回复! - Surez
3个回答

3
我知道这不是你想要的答案,但根据JavaDoc,freeMemory返回:

以字节为单位测量的当前可用于将来分配对象的总内存近似值。

为了测试它,我使用了你的代码两次。一次将数组大小设置为10,000,另一次设置为100。我还在其后添加了另一个打印输出。
Integer intArr[]= new Integer[10000];

当使用10,000时,预期结果如下:在数组实例化后,自由内存减少了40,0016字节
当使用100时,数组实例化前后具有完全相同的可用内存,这不是预期的效果。
正如大多数答案已经指出的那样,由于它是本地方法,因此对于任何平台都可能有不同的JVM依赖性而表现出不同的行为。我正在Windows 7上运行,使用内置于Eclipse v3.6的JVM。
但我认为这里的关键词是——近似值

1

刚刚检查了字节码.. 片段如下,位于两个printf之间:

SIPUSH 10000
ANEWARRAY java/lang/Integer
ASTORE 1

因此,它确实动态分配数组,并且freeMemory应该返回不同的值。由于它没有这样做,我猜它真的是平台/版本相关的,就像已经指出的那样。

例如,在我的机器上,它实际上会发生变化:

Free memory: 81915960
Free memory: 81353824

也许还有另一种猜测:也许它取决于JVM的初始堆大小参数,因此如果JVM已经开始使用足够的堆,则在达到某个阈值之前不需要分配堆(这是-Xms设置,您可以尝试增加或减少它以查看是否会发生变化)。

你可以省下这份努力 - 这不是真的。 - Ingo

1

内存是从周围的操作系统中以大块分配的。这10000个对象的组合不足以引起额外的分配。


1
这不应该是事实,因为freeMemory应该与JVM自身内部管理的内存有关,但我不确定。 - Jack
平台和JVM相关。在我的机器上运行OP的代码(Linux + Sun JVM 1.6_22),显示可用内存下降。 - Brian Roach

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