JVM进程与JVM堆内存使用情况

我已经阅读了这个Process Memory Vs Heap – JVM ,我遇到了同样的问题。

jvm进程内存使用量不断增加,从不收缩。我通过在linux服务器上做一个top来检查。 应用程序正在将作业调度到集群(使用Quartz + Sun Java DRMAA API)

Java堆空间在应用程序生命周期中保持在限制范围内,但是jvm进程显示内存使用量稳步攀升并且永远不会下降。

这是内存泄漏吗? 如果是这样,为什么堆空间在限制范围内。 有人可以解释一下。

更新:当我通过jconsole跟踪时,我有-Xmx1600m -Xms1600m我可以看到堆空间在这个限制范围内,距离为450m,但是top命令显示该进程使用了​​超过900m。

使用的总虚拟内存是最大堆+线程堆栈+直接内存+ perm gen +共享库的总和。 这永远不会缩小。

使用的实际主内存取决于占用了多少虚拟内存。 共享库是共享的,因此拥有多个JVM不会导致此内存加倍等。

JVM从不向OS释放内存,但是如果主内存长时间不使用,则可以在需要时将其换出。

实际内存消耗量大于您使用Xmx等设置的内存消耗,这是正常的。 “java将为其他事物分配内存,包括每个线程的堆栈。虚拟机的总内存消耗超过-Xmx的值并不罕见。”

参数-Xmx1600m -Xms1600m告诉JVM最少分配1600MB内存,最多分配1600MB内存。 所以JVM应该在启动时分配1600MB而从不释放它。

如果您希望JVM将内存释放回操作系统,则-Xms应该尽可能低,并且您可能必须将Java 1.7与新的G1垃圾收集器一起使用。 stefankrause.net/wp/?p=14。

使用带有-Xms32m -Xmx256m -XX的Mac OS X 10.8和Java 1.7:+ UseG1GC -XX:MinHeapFreeRatio = 5 -XX:MaxHeapFreeRatio = 10运行System.gc()后,内存将释放回操作系统。

在堆中,Java虚拟机(JVM)存储由Java应用程序创建的所有对象,例如通过使用“new”运算符。 Java垃圾收集器(gc)可以在逻辑上将堆分成不同的区域,这样gc可以更快地识别可以被删除的对象

新对象的内存在运行时在堆上分配。 实例变量存在于声明它们的对象中。

Stack是存储方法调用和局部变量的地方。 如果调用方法,则将其堆栈帧放在调用堆栈的顶部。 堆栈帧保持方法的状态,包括执行哪行代码和所有局部变量的值。 堆栈顶部的方法始终是该堆栈的当前运行方法。 线程有自己的调用堆栈。

如前所述,Java对象是在堆中创建的。 编程语言不能让程序员决定是否应该在堆栈中生成对象。 但在某些情况下,最好在堆栈上分配一个对象,因为堆栈上的内存分配比堆中的内存分配便宜,堆栈上的释放是免费的,堆栈由运行时有效管理。

因此,JVM使用内部转义分析来检查对象是否仅用于线程或方法。 如果JVM识别出这一点,它可能决定在堆栈上创建对象,从而提高Java程序的性能。 (http://www.ibm.com/developerworks/java/library/j-nativememory-linux/)