显示指定堆内存 -Xms
-Xmx
指定最小和最大堆大小
-Xms<heap size>[unit]
-Xmx<heap size>[unit]
例如
-Xms2G -Xmx5G
显式新生代内存(Young Generation)
1、指定最小、最大
-XX:NewSize=<young size>[unit]
-xx:MaxNewSize=<young size>[unit]
2、指定新生代内存
-Xmn256m
关于GC调优 很重要的一条经验是
将新对象预留在新生代,由于 Full GC 的成本远高于 Minor GC,因此尽可能将对象分配在新生代是明智的做法,实际项目中根据 GC日志分析新生代空间大小分配是否合理,适当通过“-Xmn”命令调节新生代大小,最大限度降低新对象直接进入老年代的情况。
显式指定元空间的大小
-XX:MetaspaceSize=N metaspace使用过程中触发full gc的阈值
-XX:MaxMetasapceSize=N 最大大小
垃圾回收器
-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+UseParNewGC
-XX:+UseG1GC
分别对应
- 串行垃圾收集器
- 并行垃圾收集器
- CMS垃圾收集器
- G1垃圾收集器
GC日志记录
# 必选
# 打印基本 GC 信息
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
# 打印对象分布
-XX:+PrintTenuringDistribution
# 打印堆数据
-XX:+PrintHeapAtGC
# 打印Reference处理信息
# 强引用/弱引用/软引用/虚引用/finalize 相关的方法
-XX:+PrintReferenceGC
# 打印STW时间
-XX:+PrintGCApplicationStoppedTime
# 可选
# 打印safepoint信息,进入 STW 阶段之前,需要要找到一个合适的 safepoint
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1
# GC日志输出的文件路径
-Xloggc:/path/to/gc-%t.log
# 开启日志文件分割
-XX:+UseGCLogFileRotation
# 最多分割几个文件,超过之后从头文件开始写
-XX:NumberOfGCLogFiles=14
# 每个文件上限大小,超过就触发分割
-XX:GCLogFileSize=50M
处理OOM
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./java_pid<pid>.hprof
-XX:OnOutOfMemoryError="< cmd args >;< cmd args >"
-XX:+UseGCOverheadLimit
HeapDumpOnOutOfMemoryError: JVM在遇到OOM时将heap转储到物理文件中
HeapDumpPath:要写入文件的路径
OnOutOfMemoryError 遇到OOM时发出紧急指令 比如重启服务器
UseGCOverheadLimit :限制在抛出OOM错误之前在GC中花费的VM时间的比例
JVM常见内存溢出问题
堆内存主要有两种形式的错误:
1、OutOfMemoryError:Java heap space
2、OutOfMemoryError: GC overhead limit exceeded
java heap space
在java堆中只要不断的创建对象,并且GC-Roots到对象之间存在引用链,这样JVM就不会回收对象
例如:
public static void main(String[] args) {
List<String> list = new ArrayList<>(10) ;
while (true){
list.add("1") ;
}
}
当出现 OOM 时可以通过工具来分析GC-Roots引用链,查看对象和GC-Roots是如何关联的,是否存在对象的生命周期过长
GC overhead limit exceeded
例如
public void testOom1() {
List<Map<String, Object>> mapList = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
Map<String, Object> map = new HashMap<>();
for (int j = 0; j < i; j++) {
map.put(String.valueOf(j), j);
}
mapList.add(map);
}
}
内存分析
jstat -gcutil pid 1s 5 查看5s内当前堆占用情况
输出:
- s0: 年轻代中第一个survivor区使用大小占当前容量的百分比
- s1:年轻代中第二个survivor区使用大小占用当前容量的百分比
- E:Eden区使用大小占用当前容量的百分比
- O:老年代使用大小占用当前容量的百分比
- M:元空间使用大小占用当前容量的百分比
- CCS:压缩类使用大小占用当前容量的百分比
- YGC:Young GC的次数
- YGCT:Young GC所用的时间
- FGC:Full GC的次数
- FGCT:Full GC所用的时间
- GCT:GC的所用总时间