2

简单的程序:

public class SleepTest {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(60 * 1000);
    }
}

然后

$ javac SleepTest.java 
$ java -cp . SleepTest

对于 OpenJDK 1.6.0_20,这在我的机器上使用了 600M 的虚拟内存!即“top”显示“VIRT”600M和RES 10m。(我使用的是 Ubuntu 10.04、32 位或 64 位)。

对于 Sun 的 Java 1.6.0_22,它使用 400M 的虚拟内存。

什么在使用所有虚拟内存,如何降低使用量?

完整的“java版本”:

OpenJDK:

java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.4) (6b20-1.9.4-0ubuntu1~10.04.1)
OpenJDK Client VM (build 19.0-b09, mixed mode, sharing)

太阳:

$ /usr/lib/jvm/java-6-sun-1.6.0.22/jre/bin/jav -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)

编辑

从任何一个包中使用 javac 编译似乎都没有帮助。

添加一些代码来打印已用内存如下:

private static String megabyteString(long bytes) {
    return String.format("%.1f", ((float)bytes) / 1024 / 1024); 
}
private static void printUsedMemory() {
    Runtime run = Runtime.getRuntime();
    long free = run.freeMemory();
    long total = run.totalMemory();
    long max = run.maxMemory();
    long used = total - free;
    System.out.println("Memory: used " + megabyteString(used) + "M"
            + " free " + megabyteString(free) + "M"
            + " total " + megabyteString(total) + "M"
            + " max " + megabyteString(max) + "M");
}

节目

太阳:

Memory: used 0.3M free 15.2M total 15.5M max 247.5M

OpenJDK:

Memory: used 0.2M free 15.3M total 15.5M max 494.9M

即使使用-Xmx5m,它也必须有最小值?我之前读过默认值(取决于jvm,虚拟机,默认四分之一物理内存的常用策略),但这会导致大量虚拟内存使用,我可以不减少它吗?

编辑#2

添加 -Xmx 会改变一些事情:

$ java -Xmx5m -cp . SleepTest

OpenJDK:

$ java -Xmx5m SleepTest
Memory: used 0.2M free 4.7M total 4.9M max 5.8M

为任一 JVM 使用“仅”150M 的虚拟内存。

编辑#3

nos、bestsss、Mikaveli,也许还有其他人指出虚拟内存不使用交换。nos 声称 OOM 杀手足够聪明,可以根据实际内存使用情况进行操作。如果这些事情是真的,那么我想我不关心虚拟内存的使用。RES(居民大小)很小,所以我很好。

编辑#4

不确定接受哪个答案。其中任何一个,如果它显示为答案:“不要担心,因为虚拟内存很便宜”或解释为什么 Java 保留至少 150M 的虚拟内存,无论我给它 -Xmx 或 -Xms 是什么,即使实际内存使用量很小。

编辑#5

这是一个dup。我投票关闭。

4

4 回答 4

1

“RES”是常驻集大小——本质上是您用于该进程的物理内存。

从您的示例中,top 声明它使用 10 MiB - 这大致是我对 -Xmx 设置为 5m 的预期(根据我在 *nix 系统上的 Java 经验,使用的总物理内存通常似乎是两倍。

您是否真的遇到任何内存问题,或者您只是担心“顶部”的误导性输出?

此外,*nix 虚拟内存包括可用内存空间 - 物理和交换。如果进程没有使用任何“交换”,那么它只使用物理“常驻”内存。

Stack Overflow 回答了为什么 JVM 使用比堆设置更多的内存。

于 2011-01-31T16:07:36.607 回答
1

$ java -cp 。睡眠测试-Xmx5m

哇!-Xmx5m 是一个参数,您可以在public static void main(String[] a). 它是 java 程序的参数,而不是 VM 的参数

移动它 1st $ java -Xmx5m -cp . SleepTest

于 2011-01-31T16:16:36.107 回答
0

尝试使用 -Xms 指定最小内存?

于 2011-01-31T16:01:50.343 回答
0

JVM 在计数中采用了一些堆空间(即所有内存使用)的默认值。此默认值来自机器特性(RAM、内核等)和 JVM 实现(Sun/Oracle、OpenJDK)。

我认为 -Xmx5m 太低了,JVM会默默地忽略这个参数。

这是一个很好的参考,有很多链接可供阅读:

Java 内存解释 (SUN JVM)

于 2011-01-31T16:05:55.313 回答