与JRockit相比,我在Sun的JVM上看到的最大堆大小有一些奇怪的行为。
我在64位系统(Ubuntu 11.04)上的64位VM上运行IDEA。我正在测试的JVM版本是:Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
(我使用apt-get install sun-java6-jdk
和Oracle JRockit(R) (build R28.1.3-11-141760-1.6.0_24-20110301-1432-linux-x86_64, compiled mode)
(我几个月前从Oracle网站下载的)。
如果我传递参数-Xms1g -Xmx3g,IDEA将在Sun的JVM上报告最大堆大小为1820M,在JRockit上报告3072M(如预期的那样)。
如果我通过-Xms2g -Xmx4g,IDEA将报告Sun的3640M和JRockit的4096M。
发生了什么事?什么是神秘数字1820M和3640M = 2 * 1820M?是不是可以用我想要的确切堆大小来运行Sun的JVM?
编辑:
答案已被删除,所以只是为了回复我的意见:请注意我说的是MAX尺寸,而不是当前尺寸。考虑到我在这里提出问题之前已经进行了很多研究,因此没有必要教导Xms,Xmx或任何其他指定内存区域大小的参数的含义(可以在其他地方找到)
EDIT2:
我编写了以下简单代码来测试此行为:
public static void main(String[] args) throws Exception {
while (true) {
final Runtime r = Runtime.getRuntime();
System.out.println("r.freeMemory() = " + r.freeMemory()/1024.0/1024);
System.out.println("r.totalMemory() = " + r.totalMemory()/1024.0/1024);
System.out.println("r.maxMemory() = " + r.maxMemory()/1024.0/1024);
Thread.sleep(1000);
}
}
然后我使用-Xmx100m,-Xmx110m,-Xmx120m等运行它,以获取许多不同的值,包括Sun的JVM和JRockit。 Sun将始终报告maxMemory()
的奇怪值,并且会在运行之间的大步骤(如30M)上增长。 JRockit每次报告确切的值。
答案 0 :(得分:0)
<击>
Xms
和Xmx
仅用于指示已分配堆的最小和最大大小。分配堆的实际大小可以是/将是最小值和最大值之间的值,因为JVM可以调整堆的大小,尤其是在对象分配事件或垃圾回收事件期间。
如果您需要JVM使用“精确”堆大小,您可以指定彼此足够接近的Xms
和Xmx
值,以便堆调整大小不会发生。当然,这些值必须对应于连续数量的空闲内存。
击>
上面的部分假设了其他内容,实际上可以忽略。
根据用于计算堆大小的代码,应注意Hotspot JVM的Runtime.maxMemory()
returns a value that does not correspond to the value passed in the Xmx flag;文档含糊不清,声明它只会返回一个表示the memory available for the JVM to use的值。
根据您发布的代码的行为,堆大小调整将导致为Runtime.maxMemory()
的不同调用报告不同的值。此外,不用指出JRockit JVM报告通过Xmx
标志传递的值。