JVM参数MaxNewSize的值是由什么设置的?遵守人体工程学原则吗?

8

我的服务器信息:

  • CPU:Intel Xeon E5-2630
  • 内存:65970676K
  • 操作系统:Centos 6.4
  • 内核版本:3.8.0
  • JDK版本:HotSpot JDK 1.6.0.27

我使用jmap -heap pid命令打印堆信息:

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize      = 21474836480 (20480.0MB)
NewSize          = 21757952 (20.75MB)
MaxNewSize       = 174456832 
OldSize          = 65404928 (62.375MB)
NewRatio         = 7
 SurvivorRatio    = 8
PermSize         = 268435456 (256.0MB)
MaxPermSize      = 268435456 (256.0MB)

以下是我定义运行应用程序的JVM参数:

 -verbose:gc  -XX:+UseMembar -XX:+PrintGCDetails - 
 XX:+PrintGCTimeStamps  -XX:+DisableExplicitGC - 
 XX:+CMSClassUnloadingEnabled
-XX:-OmitStackTraceInFastThrow  -Xloggc:/export/logs/gc.log 
-XX:PermSize=256m -XX:MaxPermSize=256m -Xms6G  -Xmx12G

我没有设置MaxNewSize,我尝试使用java -XX:+PrintFlagsFinal打印所有JVM参数,并发现MaxNewSize是一个非常大的数字:18446744073709486080。我认为自适应调节可能已经为我设置了MaxNewSize,值为174456832。然而,我有另一台服务器,硬件和软件都相同,但MaxNewSize392560640,其他堆参数相同。
自适应调节根据什么设置MaxNewSize的值?我能否在自适应调节的源代码中看到这个?
我认为我找到了设置MaxNewSize值的地方:Arguments.cpp(hotspot\src\share\vm\runtime)。
if (CMSUseOldDefaults) {  // old defaults: "old" as of 6.0
  if FLAG_IS_DEFAULT(CMSYoungGenPerWorker) {
    FLAG_SET_ERGO(intx, CMSYoungGenPerWorker, 4*M);
  }
  young_gen_per_worker = 4*M;
  new_ratio = (intx)15;
  min_new_default = 4*M;
  tenuring_default = (intx)0;
} else { 
  // new defaults: "new" as of 6.0
  young_gen_per_worker = CMSYoungGenPerWorker;
  new_ratio = (intx)7;
  min_new_default = 16*M;
  tenuring_default = (intx)4;
}

// Preferred young gen size for "short" pauses
const uintx parallel_gc_threads =
(ParallelGCThreads == 0 ? 1 : ParallelGCThreads);

 const size_t preferred_max_new_size_unaligned =
    ScaleForWordSize(young_gen_per_worker * parallel_gc_threads);
  const size_t preferred_max_new_size =
align_size_up(preferred_max_new_size_unaligned, os::vm_page_size());
1个回答

8
在JDK 5中,添加了自我调整JVM的性能功能,称为JVM Ergonomics。这也适用于JDK 6。当Java进程启动时,它会检查底层系统资源,并在某些选项未设置的情况下自动确定一些调整参数。换句话说,它试图通过最少的命令行调整来提供JVM的良好性能。
从J2SE平台1.2版本开始,虚拟机采用多种垃圾回收算法,使用分代收集技术。与单纯的垃圾回收不同,分代收集利用了大多数应用程序的几个经验性质,避免了额外的工作。
许多参数影响代大小。在虚拟机初始化时,将保留整个堆的空间。可以使用-Xmx选项指定保留空间的大小。如果-Xms参数的值小于-Xmx参数的值,则并非所有保留的空间都立即分配给虚拟机。未分配的空间标记为“虚拟”。需要时,堆的不同部分(永久代、老年代和年轻代)可以增长到虚拟空间的限制。
一些参数是堆的部分相对于另一部分的比率。例如,参数NewRatio表示老年代和新生代之间的相对大小。
新生代 第二个最有影响力的旋钮是用于新生代的堆的比例。新生代越大,则较少进行小型收集。然而,对于有限的堆大小,更大的新生代意味着更小的老年代,这将增加主要收集的频率。最佳选择取决于应用程序分配的对象的生命周期分布。
默认情况下,新生代大小由NewRatio控制。例如,设置-XX:NewRatio = 3表示新生代和老年代之间的比率为1:3。换句话说,伊甸园空间和幸存者空间的总大小将是总堆大小的四分之一。
参数NewSize和MaxNewSize从下方和上方限制了新生代的大小。将它们设置为相等会固定新生代,就像将-Xms和-Xmx设置为相等会固定总堆大小一样。这对于在比NewRatio允许的整数倍更细的粒度上调整新生代非常有用。
如果您需要更多关于此主题的信息,以下是一些有用的链接:

年轻代的大小由NewRatio控制。例如,设置 -XX:NewRatio=3 表示年轻代和老年代之间的比率为1:3。从jmap -heap信息可以看出,NewRatio是7,并且我在命令行上设置了 -Xms 6G。如果MaxNewSize由NewRatio计算,则应该是750M,但为什么值是392560640(374.375MB)? - user2692131
Xmx 的值是多少?可能它正在保留 750M 实际使用 ~375 并且仅显示实际使用的内存量。 - AR5HAM

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