需要排查日志的情况

1
2
3
1.在GC过程中,会Stop the World,即不干其他活,比如一段早该运行好的程序,在某个时刻卡住,业务日志上没有异常
2.通过CAT等监控工具,发现某段时间里内存用量居高不下
3.稳定重现OOM问题,比如一天一次,或每天频繁出现OOM异常

通过GC日志确认问题

java -XX:+ PrintGC -XX:+ PrintGCApplicationStopedTime SyncupData.java

1
2
3
1.能够看到GC发生时间和回收的内存量
2.能结合卡住的时间点,确认时因为GC造成的Stop the World
3.能定量观察到GC的频繁程度

RunTime类获取当前日志用量

代码展示

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MemoryOptimizationTest {

public static void main(String[] args) {

Runtime runtime = Runtime.getRuntime();

System.out.println("Java虚拟机可用的处理器数量: " + runtime.availableProcessors() + "个");
System.out.println("现阶段java虚拟机中的可用内存量: " + runtime.freeMemory()/1024L/1024L + "M");
System.out.println("现阶段java虚拟机中的内存总量: " + runtime.totalMemory()/1024L/1024L + "M");
System.out.println("java虚拟机可使用的最大内存量: " + runtime.maxMemory()/1024L/1024L + "M");

}
}

打印展示

RunTime

可使用的位置

1
2
1.可能会大规模使用内存的代码位置,可以查看执行前后的内存用量
2.运行时间可能会很长的模块: 线程池,批量导数据,频繁发起dubbo,kafka等调用

出现OOM后获取和分析Dump文件

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dump SyncupData

1
一旦出现OOM,会在指定目录下生成Dump文件,可以使用jvisualvm等工具打开,可以查看哪些对象溢出了内存

压力测试排查内存问题

1
用Jmeter等工具在测试环境上进行压力测试,即模拟发高并发的请求.压测时,用Zabbix等工具监控内存,内存用量高时,通过GC和业务日志,排查问题

总结

总结