面试问到JVM的配置,你回答以下几个常用的即可:
- 初始堆大小和最大堆大小、 栈的大小、
- 新生代和老年代的比例、
- 提高吞吐量:GCTimeRatio、
- 调整升老年代年龄、
- 打印完整堆栈信息、
- OOM时打印堆信息、
- FullGC时打印堆信息、
- 选择合适的垃圾回收器【最有效】
内存常用设置
- -Xms 初始堆大小。
- -Xmx 最大堆大小。 一般将Xms和Xmx设为一样的值,若-Xms比较小,又需要初始化很多对象,jvm就必须反复增加内存。一样大也可避免每次垃圾回收完成后JVM重新分配内存。
- -Xss 线程的栈的大小。
- -XX:NewSize=n 设置年轻代大小
- -Xmn 设置年轻代初始大小和最大大小。增大年轻代后,会减小年老代大小,此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。 等效于: 使用 -XX:NewSize 设置初始化大小并使用-XX:MaxNewSize 设置最大大小。
- -XX:NewRatio=n 设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
- -XX:SurvivorRatio=n 年轻代中Eden区与两个Survivor区的比值。
- -XX:MetaspaceSize=n 元空间大小。
- -XX:MaxMetaspaceSize=n 最大元空间大小。
实例如下
//调整内存大小
-XX:MetaspaceSize=128m(元空间默认大小)
-XX:MaxMetaspaceSize=128m(元空间最大大小)
-Xms1024m(堆最大大小)
-Xmx1024m(堆默认大小)
-Xmn256m(新生代大小)
-Xss256k(栈最大深度大小)
//调整内存比例
//伊甸园:幸存区
-XX:SurvivorRatio=8(伊甸园:幸存区=8:2)
//新生代和老年代的占比
-XX:NewRatio=4 //表示新生代:老年代 = 1:4 即老年代占整个堆的4/5;默认值=2
//修改垃圾回收器
//设置Serial垃圾收集器(新生代)
//-XX:+UseSerialGC
//设置PS+PO,新生代使用功能Parallel Scavenge 老年代将会使用Parallel Old收集器
//-XX:+UseParallelOldGC
//CMS垃圾收集器(老年代)
//-XX:+UseConcMarkSweepGC
//设置G1垃圾收集器
-XX:+UseG1GC
//GC停顿时间,垃圾收集器会尝试用各种手段达到这个时间
-XX:MaxGCPauseMillis
//进入老年代最小的GC年龄,年轻代对象转换为老年代对象最小年龄值,JDK8默认值15,JDK9默认值7
-XX:InitialTenuringThreshold=7
//新生代可容纳的最大对象,大于则直接会分配到老年代,0代表没有限制。
-XX:PretenureSizeThreshold=1000000
//使用多少比例的老年代后开始CMS收集,默认是68%,如果频繁发生SerialOld卡顿,应该调小
-XX:CMSInitiatingOccupancyFraction
//G1混合垃圾回收周期中要包括的旧区域设置占用率阈值。默认占用率为 65%
-XX:G1MixedGCLiveThresholdPercent=65
//Heap Dump(堆转储)文件
//当发生OutOfMemoryError错误时,自动生成堆转储文件。
-XX:+HeapDumpOnOutOfMemoryError
//错误输出地址
-XX:HeapDumpPath=/Users/a123/IdeaProjects/java-test/logs/dump.hprof
//GC日志
-XX:+PrintGCDetails(打印详细GC日志)
-XX:+PrintGCTimeStamps:打印GC时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps:打印GC时间戳(以日期格式)
-Xlog:gc:(打印gc日志地址)
错误信息
-XX:-OmitStackTraceInFastThrow
默认情况下,OmitStackTraceInFastThrow 这个参数是开启的,即:-XX:+OmitStackTraceInFastThrow,此时如果程序多次发生了同一个异常,将不打印完整堆栈信息,只打印简略信息。以空指针异常为例,如果很多次空指针异常,将会打印以下信息:
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
这样就导致有时候排查问题非常不方便(很多研发对此无能为力),我们这里把它关闭,方法是:-XX:-OmitStackTraceInFastThrow。
GC的常用设置
-XX:+PrintGC 打印 GC 日志
-XX:+PrintGCDetails 打印详细 GC 日志
-XX:+PrintGCTimeStamps GC时,打印进程启动到现在经历的时间
-XX:+PrintGCApplicationConcurrentTime 打印每次垃圾回收前程序未中断的执行时间。可与上面混合使用
-XX:+PrintGCApplicationStoppedTime 打印 STW 时间。
-XX:PrintHeapAtGC 打印GC前后的详细堆栈信息
-XX:+PrintTenuringDistribution 打印对象年龄分布,对调优 MaxTenuringThreshold 参数帮助很大
-Xloggc:/tmp/logs/gc_%p.log 将以上 GC 内容输出到文件中
OOM信息常用设置
-XX:+HeapDumpOnOutOfMemoryError 开启堆转储功能。当Java应用抛出OutOfMemoryError异常时会用堆转储工具(HPROF)将Java堆存储到文件中。
可使用选项-XX:HeapDumpPath=path指定文件路径。
-XX:HeapDumpPath=/tmp/logs Dump 文件保存路径
-XX:ErrorFile=/tmp/logs/hs_error_pid%p.log 错误日志存放路径
Full GC常用设置
-XX:+HeapDumpBeforeFullGC 在Full GC前生成dump文件
-XX:+HeapDumpAfterFullGC 在Full GC后生成dump文件
-XX:HeapDumpPath=/tmp/FullGC 设置Dump保存的路径
收集器常用设置
-XX:+UseSerialGC // 设置串行收集器
-XX:+UseParallelGC // 设置并行收集器
-XX:+UseParalledlOldGC // 设置并行年老代收集器
-XX:+UseConcMarkSweepGC // 设置并发收集器
并行收集器设置
-XX:ParallelGCThreads=n // 设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n //设置并行收集最大暂停时间
-XX:GCTimeRatio=n //设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
并发收集器设置
-XX:+CMSIncrementalMode
设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads=n
设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。
【最有效】选择合适的垃圾回收器
JVM调优最实用、最有效的方式是升级垃圾回收器,根据CPU核数,升级当前版本支持的最新回收器。
CPU单核,那么毫无疑问Serial 垃圾收集器是你唯一的选择。
CPU多核,关注吞吐量 ,那么选择Parallel Scavenge+Parallel Old组合(JDK8默认)。
CPU多核,关注用户停顿时间,JDK版本1.6或者1.7,那么选择ParNew+CMS,吞吐量降低但是低停顿。
CPU多核,关注用户停顿时间,JDK1.8及以上,JVM可用内存6G以上,那么选择G1。
例如:
//修改垃圾回收器
//设置Serial垃圾收集器(新生代)
-XX:+UseSerialGC
本人也在学习中,更多JVM调优内容可参考其他作者的内容
链接:https://blog.csdn.net/qq_40991313/article/details/132382094