引言
在我们使用的中间件中如websphere、weblogic等都会对JVM堆的参数进行相关设置,其目的是为了更好的完成JVM的垃圾回收,充分发挥中间件的性能。
参数意义
JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制(在硬件条件允许的情况下设置)。
在我们启动如weblogic服务的时候,如果你注意,可以看到如下的一段信息:
java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0 -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy XX:+UseConcMarkSweepGC -XX:+UseParNewGC
这些信息到底代表的是什么意义呢?接下来,我向你解释一下,因为你使用这些参数中的一些,或者是全部会对我们的系统的稳定运行是有影响的。JVM的堆主要分为3块:年轻代(包含Eden和两个Survivor)、年老代和持久代。
这里以weblogic为例。在weblogic8系列以前的版本中,对JVM堆的参数设置是在bin目录下"setWeblogic.cmd/sh"文件中完成。从weblogic9系列开始,这些参数只要是在bin目录下"setDomianEnv.cmd/sh"文件中完成,并执行后生效。
这些参数的意义如下:
-Xmx3550m: 设置JVM最大可用内存为3550M。
-Xms3550m: 设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g: 设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,官方推荐配置为整个堆的3/8。
-Xss128k: 设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。
-XX:NewRatio=4 :设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。
-XX:SurvivorRatio=4 :设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6 。
-XX:MaxPermSize=16m: 设置持久代大小为16m。
-XX:MaxTenuringThreshold=0: 设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
-XX:+UseParallelGC: 选择垃圾收集器为并行收集器。 此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
-XX:ParallelGCThreads=20: 配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
-XX:+UseParallelOldGC: 配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集。
-XX:MaxGCPauseMillis=100 :设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。
-XX:+UseAdaptiveSizePolicy :设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开。
-XX:+UseConcMarkSweepGC: 设置年老代为并发收集。-XX:+UseParNewGC: 设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值。
经验总结
很多参数的设置和调整与JDK的版本有直接的关系,如回收器的选择有: 串行收集器、并行收集器、并发收集器 ,但是串行收集器只适用于小数据量的情况,所以最好选择并行收集器和并发收集器。但是JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数就必须使用JDK6.0以上版本。
有关JVM堆的参数有很多,但是并不是设置的越多就越能发挥JVM的性能。其实在这些参数设置完成启动后,都或多或少的占用部分系统的资源,造成系统资源负担较大。我们要结合业务环境的实际情况,逐步来调整和添加这些参数,让JVM为我们服务更加稳定。