对照官网参数说明,将一些常用的配置摘出来分析一下:
-Xms:
设置堆的最小大小和初始大小(以字节为单位)。此值必须是1024的倍数且大于1 MB。附加字母k或k表示千字节,m或m表示兆字节,g或g表示千兆字节。默认为物理内存的1/64(<1GB)
-Xms6291456-Xms6144k-Xms6m
-Xmx:
以字节为单位指定内存分配池的最大大小(以字节为单位)。此值必须是1024的倍数且大于2 MB。附加字母k或k表示千字节,m或m表示兆字节,g或g表示千兆字节。默认值是根据系统配置在运行时选择的。对于服务器部署,-Xms和-Xmx通常设置为相同的值。默认为物理内存的1/4(<1GB)
-XX:NewSize:
设置年轻代初始堆大小,堆的年轻代区域用于新对象。GC在这个区域比在其他区域执行的频率更高。如果年轻一代的规模太小,那么将进行大量的小型GCs。如果大小太大,那么只执行完整的GCs,这可能需要很长时间才能完成。Oracle建议将年轻一代的大小保持在堆总大小的一半到四分之一之间。(该值需要小于-Xms的值)
-XX:MaxNewSize:
设置年轻代堆最大大小。(该值需要小于-Xmx的值)
-Xmn:
设置年轻代堆的初始大小和最大大小(字节)。至于这个参数则是对 -XX:newSize、-XX:MaxnewSize两个参数的同时配置,也就是说如果通过-Xmn来配置新生代的内存大小,那么-XX:newSize = -XX:MaxnewSize = -Xmn,虽然会很方便,但需要注意的是这个参数是在JDK1.4版本以后才使用的。
-Xss:(堆栈大小是平台默认的,不需要我们调整设置)
设置线程堆栈大小(以字节为单位)。附加字母k或k表示KB,m或m表示MB,g或g表示GB。默认值取决于平台:
-XX:ThreadStackSize:
设置线程堆栈大小,-Xss和-XX:ThreadStackSize
分别是OpenJDK和Oracle JDK 的别名.
-Xss
可以接受带有K,M或G后缀的数字;
-XX:ThreadStackSize=
需要一个整数(不带后缀) – 堆栈大小,以千字节为单位.
比例方式设置
-XX:NewRatio:
设置年轻代和老年代大小之间的比率。默认情况下,此选项设置为2,eg:-XX:NewRatio=2
-XX:SurvivorRatio:
设置Eden空间大小和幸存者空间大小之间的比率。默认情况下,此选项设置为8。表示:Eden:from:to=8:1:1 eg:-XX:SurvivorRatio=8
-XX:MinHeapFreeRatio:
设置GC事件后允许的最小可用堆空间百分比(0到100)。如果可用堆空间低于此值,则堆将被扩展。默认情况下,此值设置为40%。 eg:-XX:MinHeapFreeRatio=40
-XX:MaxHeapFreeRatio:
设置GC事件后允许的最大可用堆空间百分比(0到100)。如果可用堆空间高于此值,则堆将被缩小。默认情况下,此值设置为70%。 eg:-XX:MaxHeapFreeRatio=70
-XX:PermSize:
设置持久代的初始值,默认值物理内存的1/64。
-XX:MaxPermSize:
设置持久代的最大值,默认值物理内存的1/4。
-XX:PermSize和-XX:MaxPermSize这两个参数在jdk8中已经被弃用,用
-XX:MetaspaceSize: 和-XX:MaxMetaspaceSize: 取代。
-XX:MetaspaceSize:
设置元空间的初始大小,该空间将在第一次超出时触发垃圾回收。垃圾收集的阈值根据使用的元数据量增加或减少。默认大小取决于平台。
-XX:MaxMetaspaceSize:
设置元空间的最大大小
-XX:MaxDirectMemorySize:
JVM堆内存大小可以通过-Xmx来设置,同样的direct ByteBuffer可以通过-XX:MaxDirectMemorySize来设置,此参数的含义是当Direct ByteBuffer分配的堆外内存到达指定大小后,即触发Full GC。注意该值是有上限的,默认是64M,最大为sun.misc.VM.maxDirectMemory(),在程序中中可以获得-XX:MaxDirectMemorySize的设置的值。
-verbose:gc:
显示有关每个垃圾回收(GC)事件的信息。
-Xloggc:
设置详细GC时间信息重定向到文件进行日志记录,eg: -Xloggc:logs/gc.log
下面这个输出信息是线上gc.log的部分日志信息:
-XX:+UseParNewGC:
允许在年轻代中使用并行线程进行收集。默认情况下,此选项处于禁用状态。设置该-XX:+UseConcMarkSweepGC
选项时,它将自动启用。使用-XX:+UseParNewGC
不带选项-XX:+UseConcMarkSweepGC
的选择是在JDK 8弃用。
-XX:+UseConcMarkSweepGC:
允许老年代使用CMS垃圾收集器。当吞吐量(-XX:+usepallelgc)垃圾收集器无法满足应用程序延迟要求时,Oracle建议您使用CMS垃圾收集器。G1垃圾收集器(-XX:+UseG1GC)是另一种选择。
默认情况下,此选项处于禁用状态,并且根据机器的配置和JVM的类型自动选择收集器。启用此选项后,会自动设置-XX:+UseParNewGC选项,您不应该禁用它,因为JDK 8中不推荐使用以下选项组合:-XX:+useConMarkSweepGC -XX:-UseParNewGC。
-XX:UseParallelGC:
允许使用并行清除垃圾收集器(也称为吞吐量收集器),以利用多个处理器来提高应用程序的性能。默认情况下,此选项是禁用的,并且将根据计算机的配置和JVM的类型自动选择收集器。如果已启用,则-XX:+UseParallelOldGC
除非您明确禁用它,否则该选项将自动启用。
JDK1.8默认就是以下组合-XX:+UseParallelGC 新生代使用ParallelScavenge,老年代使用ParallelOld
-XX:UseParallelOldGC:
允许将并行垃圾收集器用于完整的GC。默认情况下,此选项处于禁用状态。启用它会自动启用该-XX:+UseParallelGC
选项。
-XX:MaxGCPauseMillis:
设置最大GC暂停时间的目标(以毫秒为单位)。这是一个软目标,并且JVM将尽最大的努力来实现它。默认情况下,没有最大暂停时间值。
-XX:MaxGCPauseMillis = 500
-XX:GCTimeRatio: (java8没有)
-XX:GCTimeRatio参数的值则应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率,相当于吞吐量的倒数。例如:把此参数设置为19,那允许的最大垃圾收集时占用总时间的5%(即1/(1+19)),默认值为99,即允许最大1%(即1/(1+99))的垃圾收集时间由于与吞吐量关系密切,ParallelScavenge是“吞吐量优先垃圾回收器”。
-XX:UseAdaptiveSizePolicy:
启用自适应生成大小调整。默认情况下启用此选项。要禁用自适应生成大小调整.
这是一个开关参数,当这个参数被激活之后,就不需要人工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。
-XX:GCTimeRatio参数的值则应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率,相当于吞吐量的倒数。例如:把此参数设置为19,那允许的最大垃圾收集时占用总时间的5%(即1/(1+19)),默认值为99,即允许最大1%(即1/(1+99))的垃圾收集时间由于与吞吐量关系密切,ParallelScavenge是“吞吐量优先垃圾回收器”。
-XX:ParallelGCThreads:
设置年轻和旧代中用于并行垃圾收集的线程数。默认值取决于JVM可用的CPU数量。
-XX:+PrintGCTimeStamps:
允许在每个GC打印时间戳。默认情况下,此选项处于禁用状态。
-XX:+PrintGCDetails:
支持在每个GC打印详细消息。默认情况下,此选项处于禁用状态。
示例说明
运行参数: -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
一段gc信息如下:
0.123: [GC (System.gc()) [PSYoungGen: 2029K->496K(2560K)] 2029K->740K(9728K), 0.0034123 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
0.126: [Full GC (System.gc()) [PSYoungGen: 496K->0K(2560K)] [ParOldGen: 244K->670K(7168K)] 740K->670K(9728K), [Metaspace: 3073K->3073K(1056768K)], 0.0042940 secs] [Times: user=0.13 sys=0.00, real=0.01 secs]
0.123是从jvm启动直到垃圾收集发生所经历的时间,GC表示这是一次Minor GC(新生代垃圾收集);PSYoungGen,表示新生代使用的是多线程垃圾收集器Parallel Scavenge。
2029K表示垃圾收集之前新生代占用空间,496K表示垃圾收集之后新生代的空间,新生代又细分为一个Eden区和两个Survivor区,Minor GC之后Eden区为空,496K就是Survivor占用的空间。括号里的2560K表示整个年轻代的大小.
2029K->740K(9728K),表示垃圾收集之前(2029K)与之后(740K)Java堆的使用大小(总堆9728K,堆大小包括新生代和年老代)
老年代堆大小为:9728K-2560K=7168K,与下面的Full GC显示的老年代堆大小一致。
老年代Full GC之前占用244K,Survivor占用496K,244K +496K = 740K是整个推使用大小。
0.0034123 secs是本次Minor GC消耗的时间
[Times: user=0.00 sys=0.00, real=0.00 secs] 提供cpu使用及时间消耗,user是用户模式垃圾收集消耗的cpu时间,实例中垃圾收集器消耗了0.00秒用户态cpu时间,sys是消耗系统态cpu时间,real是指垃圾收集器消耗的实际时间。
[Metaspace: 3073K->3073K(1056768K)] 元空间GC之前和之后占用大小没有变化3073K,元空间大小为1056768K。
完整打印信息下面一部分打印截图
上面我们运行参数设置的堆大小是10M,根据上图我们可以看出,年轻代的大小是Eden+1个Survivor区大小,整个堆大小=2560K+512K+7168K=10M
-Xnoclassgc:
禁用类的垃圾收集(GC)。这可以节省一些GC时间,从而缩短应用程序运行期间的中断。当您在启动时指定-Xnoclassgc时,应用程序中的类对象将在GC期间保持不变,并且始终被视为活动的。这会导致更多的内存被永久占用,如果不小心使用,会引发内存不足异常。
-XX:PretenureSizeThreshold:(java8没有)
HotSpot虚拟机提供了-XX:PretenureSizeThreshold参数,指定大于该设置值的对象直接在老年代分配,这样做的目的就是避免在Eden区及两个Survivor区之间来回复制,产生大量的内存复制操作。
这样做的目的:1.避免大量内存复制,2.避免提前进行垃圾回收,明明内存有空间进行分配。PretenureSizeThreshold参数只对Serial和ParNew两款收集器有效。
-XX:PretenureSizeThreshold=4m
-XX:MaxTenuringThreshold:
设置用于自适应GC大小调整的最大使用期限阈值。最大值为15。并行(吞吐量)收集器的默认值为15,而CMS收集器的默认值为6。
如果对象在Eden出生并经过第一次MinorGC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并将对象年龄设为1,对象在Survivor区中每熬过一次MinorGC,年龄就增加1,当它的年龄增加到一定程度(并发的垃圾回收器默认为15),CMS是6时,就会被晋升到老年代中。
为了能更好地适应不同程序的内存状况,虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄
-XX:HandlePromotionFailure: (java8没有)
在发生MinorGC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么MinorGC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次MinorGC,尽管这次MinorGC是有风险的,如果担保失败则会进行一次FullGC;如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次FullGC。
HandlePromotionFailure=true
-XX:ErrorFile
指定发生不可恢复的错误时将错误数据写入的路径和文件名。默认情况下,此文件在当前工作目录中创建,并命名为hs_err_pidpid.log,其中pid是导致错误的进程的标识符。以下示例显示了如何设置默认日志文件(请注意,该进程的标识符指定为%p):
-XX:ErrorFile =。/ hs_err_pid%p.log
以下示例显示了如何将错误日志设置为/var/log/java/java_error.log:
-XX:ErrorFile = / var / log / java / java_error.log
如果由于空间不足,权限问题或其他问题而无法在指定目录中创建文件,则将在操作系统的临时目录中创建文件。临时目录为/tmp。
-XX:OnOutOfMemoryError:
href="">设置在OutOfMemoryError第一次引发异常时运行的自定义命令或一系列用分号分隔的命令。如果字符串包含空格,则必须将其用引号引起来
-XX:+ HeapDumpOnOutOfMemoryError:
java.lang.OutOfMemoryError引发异常时,使用堆分析器(HPROF)启用将Java堆转储到当前目录中的文件的功能。您可以使用该-XX:HeapDumpPath选项显式设置堆转储文件的路径和名称。默认情况下,禁用此选项,并且在OutOfMemoryError引发异常时不转储堆。
-XX:HeapDumpPath:
设置-XX:+HeapDumpOnOutOfMemoryError选项时,设置用于写入由堆分析器(HPROF)提供的堆转储的路径和文件名。默认情况下,在当前工作目录中创建该文件,并将其命名为java_pidpid.hprof,其中pid是导致错误的进程的标识符。以下示例显示如何显式设置默认文件(%p代表当前进程标识符):
-XX:HeapDumpPath =。/ java_pid%p.hprof
以下示例显示如何将堆转储文件设置为/var/log/java/java_heapdump.hprof:
-XX:HeapDumpPath = / var / log / java / java_heapdump.hprof
-XX:LogFile:
设置写入日志数据的路径和文件名。默认情况下,该文件在当前工作目录中创建,并命名为hotspot.log。
以下示例显示如何将日志文件设置为/var/log/java/hotspot.log:
-XX:LogFile = / var / log / java / hotspot.log
我经历的某个线上项目,当前的jvm参数配置如下:
-Xmx2700m // 最大堆内存 -Xms200m // 初始堆内存-verbose:gc -Xloggc:logs/gc.log // 记录gc并打印日志-XX:ThreadStackSize=256 // 线程堆栈256kb-XX:MaxPermSize=256M // 持久代最大值 -XX:PermSize=256M // 持久代最小值-XX:+UseParNewGC // 年轻代采用并行收集-XX:+PrintGCTimeStamps // gc时打印时间戳-XX:+PrintGCDetails // 打印gc详细信息
当前情况周一到周五在线人数3000上下,周六周日可能多个1000-2000人,线上的jvm信息如下:
游戏数据量不是很客观,所以我们看到的内存使用最大量是407M,非堆内存用了57.5M。