【JVM】总结篇之GC日志分析 和 案例

文章目录

GC日志参数

GC日志格式

GC日志分类

MinorGC

MinorGC(或young GC或YGC)日志:

GC (Allocation Failure) \[PSYoungGen: 31744K-\>2192K(36864K)\] 31744K-\>2200K(121856K), 0.0139308 secs\] \[Times: user=0.05 sys=0.01, real=0.01 secs

FullGC

Full GC日志介绍:

Full GC (Metadata GC Threshold) \[PSYoungGen: 5104K-\>0K(132096K)\] \[ParOldGen: 416K-\>5453K(50176K)\] 5520K-\>5453K(182272K), \[Metaspace: 20637K-\>20637K(1067008K)\], 0.0245883 secs\] \[Times: user=0.06 sys=0.00, real=0.02 secs

文件概念




gceasy-在线分析gc文件

OOM

说到内存泄漏,问有没有碰到,内存泄漏怎么解决?(拼多多)

内存泄漏是怎么造成的?(拼多多、字节跳动)

如何理解内存泄漏问题?有哪些情况会导致内存泄露?如何解决? (阿里)

OOM案例1:堆溢出

java.lang.OutOfMemoryError: Java heap space

java 复制代码
@RequestMapping("/add")
public void addObject(){
    ArrayList<People> people = new ArrayList<>();
    while (true){
        people.add(new People());
    }
}
 
@Data
public class People {
    private String name;
    private Integer age;
    private String job;
    private String sex;
}

参数配置: 初始 -Xms30M -Xmx30M

-XX:+PrintGCDetails -XX:MetaspaceSize=64m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap/heapdump.hprof -XX:+PrintGCDateStamps -Xms200M -Xmx200M -Xloggc:log/gc-oomHeap.log


dump文件分析

1 jvisualvm分析

jvisualvm工具分析堆内存文件heapdump.hprof

概要 类

2 MAT分析

到对应的线程及相应线程中对应实例的位置和代码

OOM案例2:元空间溢出

java.lang.OutOfMemoryError: Metaspace

垃圾收集行为在这个区域是比较少出现的,其内存回收目标主要是针对常量池的回收和对类型的卸载。当方法区无法满足内存分配需求时,将抛出 OutOfMemoryError 异常。

java 复制代码
/**
 * 案例2:模拟元空间OOM溢出
 */
@RequestMapping("/metaSpaceOom")
public void metaSpaceOom(){
    ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
    while (true){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(People.class);
        enhancer.setUseCache(false);
        enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
            System.out.println("我是加强类哦,输出print之前的加强方法");
            return methodProxy.invokeSuper(o,objects);
        });
        People people = (People)enhancer.create();
        people.print();
        System.out.println(people.getClass());
        System.out.println("totalClass:" + classLoadingMXBean.getTotalLoadedClassCount());
        System.out.println("activeClass:" + classLoadingMXBean.getLoadedClassCount());
        System.out.println("unloadedClass:" + classLoadingMXBean.getUnloadedClassCount());
    }
}
 
 
public class People {
    public void print(){
       System.out.println("我是print本人");
    }
}

-XX:+PrintGCDetails -XX:MetaspaceSize=60m -XX:MaxMetaspaceSize=60m -Xss512K -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap/heapdumpMeta.hprof -XX:SurvivorRatio=8 -XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:+PrintGCDateStamps -Xms60M -Xmx60M -Xloggc:log/gc-oomMeta.log


java 复制代码
2021-04-21T00:04:09.052+0800: 109.779: [GC (Metadata GC Threshold) [PSYoungGen: 174K->32K(19968K)] 14926K->14784K(60928K), 0.0013218 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:09.054+0800: 109.780: [Full GC (Metadata GC Threshold) [PSYoungGen: 32K->0K(19968K)] [ParOldGen: 14752K->14752K(40960K)] 14784K->14752K(60928K), [Metaspace: 58691K->58691K(1103872K)], 0.0274454 secs] [Times: user=0.17 sys=0.00, real=0.03 secs] 
2021-04-21T00:04:09.081+0800: 109.808: [GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] 14752K->14752K(60928K), 0.0009630 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:09.082+0800: 109.809: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] [ParOldGen: 14752K->14752K(40960K)] 14752K->14752K(60928K), [Metaspace: 58691K->58691K(1103872K)], 0.0301540 secs] [Times: user=0.17 sys=0.00, real=0.03 secs] 
2021-04-21T00:04:22.476+0800: 123.202: [GC (Metadata GC Threshold) [PSYoungGen: 3683K->384K(19968K)] 18435K->15144K(60928K), 0.0015294 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:22.477+0800: 123.203: [Full GC (Metadata GC Threshold) [PSYoungGen: 384K->0K(19968K)] [ParOldGen: 14760K->14896K(40960K)] 15144K->14896K(60928K), [Metaspace: 58761K->58761K(1103872K)], 0.0299402 secs] [Times: user=0.16 sys=0.02, real=0.03 secs] 
2021-04-21T00:04:22.508+0800: 123.233: [GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] 14896K->14896K(60928K), 0.0016583 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:22.509+0800: 123.235: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] [ParOldGen: 14896K->14751K(40960K)] 14896K->14751K(60928K), [Metaspace: 58761K->58692K(1103872K)], 0.0333369 secs] [Times: user=0.22 sys=0.02, real=0.03 secs] 
2021-04-21T00:04:22.543+0800: 123.269: [GC (Metadata GC Threshold) [PSYoungGen: 229K->320K(19968K)] 14981K->15071K(60928K), 0.0014224 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:22.544+0800: 123.271: [Full GC (Metadata GC Threshold) [PSYoungGen: 320K->0K(19968K)] [ParOldGen: 14751K->14789K(40960K)] 15071K->14789K(60928K), [Metaspace: 58692K->58692K(1103872K)], 0.0498304 secs] [Times: user=0.42 sys=0.00, real=0.05 secs] 
2021-04-21T00:04:22.594+0800: 123.321: [GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] 14789K->14789K(60928K), 0.0016910 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:22.596+0800: 123.322: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] [ParOldGen: 14789K->14773K(40960K)] 14789K->14773K(60928K), [Metaspace: 58692K->58692K(1103872K)], 0.0298989 secs] [Times: user=0.16 sys=0.02, real=0.03 secs] 
2021-04-21T00:04:22.626+0800: 123.352: [GC (Metadata GC Threshold) [PSYoungGen: 0K->0K(19968K)] 14773K->14773K(60928K), 0.0013409 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:22.627+0800: 123.354: [Full GC (Metadata GC Threshold) [PSYoungGen: 0K->0K(19968K)] [ParOldGen: 14773K->14765K(40960K)] 14773K->14765K(60928K), [Metaspace: 58692K->58692K(1103872K)], 0.0298311 secs] [Times: user=0.17 sys=0.00, real=0.03 secs] 
2021-04-21T00:04:22.657+0800: 123.384: [GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] 14765K->14765K(60928K), 0.0014417 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-04-21T00:04:22.659+0800: 123.385: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(19968K)] [ParOldGen: 14765K->14765K(40960K)] 14765K->14765K(60928K), [Metaspace: 58692K->58692K(1103872K)], 0.0253914 secs] [Times: user=0.30 sys=0.00, real=0.03 secs] 

可以看到FullGC是由于方法区空间不足引起的

OOM案例3:GC overhead limit exceeded

OutOfMemoryError: GC overhead limit exceeded 是 Java 虚拟机(JVM)抛出的一个错误,表明虽然堆内存没有完全被耗尽,但是垃圾收集器(GC)花费了太多时间来回收很少量的内存空间,效率低下。具体来说,当超过 98% 的 GC 时间都用来回收不到 2% 的堆内存时,就会抛出此错误。

java 复制代码
public class OOMTest {
    public static void main(String[] args) {
       int i = 0;
    List<String> list = new ArrayList<>();
    try {
        while (true) {
           list.add(UUID.randomUUID().toString().intern());
           i++;
        }
    } catch (Throwable e) {
        System.out.println("************i: " + i);
        e.printStackTrace();
        throw e;
    }
 
}

-XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap/dumpExceeded.hprof -XX:+PrintGCDateStamps -Xms10M -Xmx10M -Xloggc:log/gc-oomExceeded.log

java 复制代码
[Full GC (Ergonomics) [PSYoungGen: 2047K->2047K(2560K)] [ParOldGen: 7110K->7095K(7168K)] 9158K->9143K(9728K), [Metaspace: 3177K->3177K(1056768K)], 0.0479640 secs] [Times: user=0.23 sys=0.01, real=0.05 secs] 
java.lang.OutOfMemoryError: GC overhead limit exceeded
[Full GC (Ergonomics) [PSYoungGen: 2047K->2047K(2560K)] [ParOldGen: 7114K->7096K(7168K)] 9162K->9144K(9728K), [Metaspace: 3198K->3198K(1056768K)], 0.0408506 secs] [Times: user=0.22 sys=0.01, real=0.04 secs] 

通过查看GC日志可以发现,系统在频繁性的做FULL GC,但是却没有回收掉多少空间,那么引起的原因可能是因为内存不足,也可能是存在内存泄漏的情况,接下来我们要根据堆dump文件来具体分析。

java 复制代码
对比代码,发生Java heap space:不停的追加str
  public static void main(String[] args) {
        String str = "";
        Integer i = 1;
        try {
        while (true) {
            i++;
            str += UUID.randomUUID();
        }}catch (Throwable e) {
            System.out.println("************i: " + i);
            e.printStackTrace();
            throw e;
        }
}

-XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap/dumpHeap1.hprof -XX:+PrintGCDateStamps -Xms10M -Xmx10M -Xloggc:log/gc-oomHeap1.log

分析及解决:

第1步:定位问题代码块 (jvisualvm分析 MAT分析)

第2步:分析dump文件直方图

第3步:代码修改

OOM案例4:线程溢出

java.lang.OutOfMemoryError : unable to create new native Thread

出现这种异常,基本上都是创建了大量的线程导致的

相关推荐
秋名RG2 小时前
浅谈Java 内存管理:栈与堆,垃圾回收
java·开发语言·jvm
xxxmine2 小时前
JVM——运行时数据区
jvm
多多*5 小时前
非关系型数据库 八股文 Redis相关 缓存雪崩 击穿 穿透
java·开发语言·jvm·数据库·redis·缓存·nosql
木昜先生6 小时前
知识点:深入理解 JVM 内存管理与垃圾回收
java·jvm·后端
碎梦归途9 小时前
23种设计模式-行为型模式之备忘录模式(Java版本)
java·jvm·设计模式·软考·备忘录模式·软件设计师·行为型模式
oioihoii2 天前
C++23 中 static_assert 和 if constexpr 的窄化布尔转换
java·jvm·c++23
jzshmyt2 天前
大内存生产环境tomcat-jvm配置实践
java·jvm·tomcat
左灯右行的爱情2 天前
JVM-类加载机制
jvm
左灯右行的爱情2 天前
深入理解 G1 GC:已记忆集合(RSet)与收集集合(CSet)详解
java·jvm·后端·juc
智商低情商凑3 天前
CAS(Compare And Swap)
java·jvm·面试