Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,什么在虚拟内存中使用400M?我如何降低这种使用?_Java_Performance_Virtual Memory - Fatal编程技术网

在Java中,什么在虚拟内存中使用400M?我如何降低这种使用?

在Java中,什么在虚拟内存中使用400M?我如何降低这种使用?,java,performance,virtual-memory,Java,Performance,Virtual Memory,简单程序: public class SleepTest { public static void main(String[] args) throws InterruptedException { Thread.sleep(60 * 1000); } } 然后 对于OpenJDK 1.6.020,这在我的机器上使用了600万虚拟内存!也就是说,“top”显示“VIRT”600米,RES 10米。(我使用的是Ubuntu 10.04,32位或64位) 对于Sun

简单程序:

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

对于OpenJDK 1.6.020,这在我的机器上使用了600万虚拟内存!也就是说,“top”显示“VIRT”600米,RES 10米。(我使用的是Ubuntu 10.04,32位或64位)

对于Sun的Java 1.6.022,它使用了400米的虚拟内存

是什么在使用这些虚拟内存,如何降低这些虚拟内存的使用率?

完整的“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)
Memory: used 0.2M free 15.3M total 15.5M max 494.9M
$ java -Xmx5m SleepTest
Memory: used 0.2M free 4.7M total 4.9M max 5.8M
太阳报:

编辑

从这两个包中使用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");
}
显示

太阳报:

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)
Memory: used 0.2M free 15.3M total 15.5M max 494.9M
$ java -Xmx5m SleepTest
Memory: used 0.2M free 4.7M total 4.9M max 5.8M
即使使用-Xmx5m,它也必须有一个最小值?我以前读过关于默认值的文章(取决于jvm、虚拟机,默认情况下,这是一种常见的策略,占物理内存的四分之一),但这是否会导致大量虚拟内存的使用,并且我不能减少它

编辑#2

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

$ java -Xmx5m -cp . SleepTest
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)
Memory: used 0.2M free 15.3M total 15.5M max 494.9M
$ 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在虚拟内存中至少保留了1.5亿内存,不管我给它-Xmx或-Xms,即使实际内存使用量很小

编辑#5


这是一个很好的例子。我投票决定关闭。

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

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

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

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

“RES”是常驻设置大小-本质上是用于该进程的物理内存

在您的示例中,top表示它使用的是10个MiB—这大概是我所期望的-Xmx设置为5m的情况(根据我对Java on*nix系统的经验,使用的总物理内存似乎经常是原来的两倍)

您是否真的遇到了内存问题,或者您只是担心来自“top”的误导性输出

另外,*nix虚拟内存包括可用内存空间的一部分—物理内存和交换内存。如果进程不使用任何“交换”,那么它只使用物理“驻留”内存

$java-cp.SleepTest-Xmx5m

哇!可以在
publicstaticvoidmain(String[]a)
找到-Xmx5m参数,它是java程序的参数,而不是VM的参数

先走一步
$java-Xmx5m-cp.SleepTest

如果没有更多信息,我们无法确定太多内容(您也一样)。您应该运行该程序并获得堆转储。针对运行Java应用程序的pid运行jmap,然后在Eclipse MAT之类的工具中对其进行解析。您可能会发现另一个有用的工具是VisualVM。您为什么担心虚拟内存大小?地址空间是否用完?约翰V:拜托,这是一个五行程序,几乎没有内存堆转储显示了很小的使用量,当然不是100秒的meg。如果虚拟内存包含代码段(我假设是这样读取的),那么我就不用担心了。代码不会进入交换,因为它总是可以根据需要从二进制文件中加载。因此,这基本上意味着Java有150 MB的二进制文件可以从中加载代码,但它在必要时才会这样做(这在大多数代码中是不可能发生的)。“我认为-Xmx5m太低了”--并不是说,参数位置错了,它必须在SleepTestI修复参数的位置之前。是的,我发现并修复了它。仍然是150M的虚拟内存使用量。你希望它是多少?你知道虚拟内存是什么,对吗?很好!我一直认为虚拟内存进行了交换,但似乎不是这样。解释ned在上面的@biziclop回答中:试图避免OOM杀手和巨大的磁盘空间使用。您确实意识到*nix虚拟内存是完整的内存空间,而不仅仅是交换。与Windows的虚拟“交换”内存不同。@Mikaveli:我没有意识到!我想这对我来说不是问题。当您查看“顶部”的输出时,在大多数版本中,有一个特定的交换列-这是使用磁盘空间的内存。如果堆使用的驻留集大小非常低(10 MiB),我怀疑它是否会溢出到交换中。我相信Ubuntu default top没有这个列。我以前从未见过,但我愿意相信它存在。“java-Xms5m-Xmx5m SleepTest”仍然使用150M的虚拟内存。