堆栈溢出的排查过程-cpu100%

JVM内存模型与JAVA内存模型

JVM内存模型

  • :主要存放对象实例
  • 方法区:运行时常量池、静态变量、常量、字段、方法字节码
  • java栈(虚拟机栈):主要存储特定线程的方法调用状态
  • 本地方法栈:存储本地方法的调用状态
  • 程序计数器:指定到下一条要执行的字节码指令

JAVA内存模型

  • 主内存:java虚拟机规定所有的变量(不是程序中的变量)都必须在主内存中产生,为了方便理解,可以认为是堆区。)
  • 工作内存:每条线程都有自己的工作内存(Working Memory,又称本地内存,可与前面介绍的处理器高速缓存类比),线程的工作内存中保存了该线程使用到的变量的主内存中的共享变量的副本拷贝。工作内存是 JMM 的一个抽象概念,并不真实存在。

溢出是发生在堆中

  • JVM堆内存被分为两部分:年轻代(Young Generation)和⽼年代(Old Generation)

年轻代

  • 年轻代是所有新对象产⽣的地⽅。当年轻代内存空间被⽤完时,就会触发垃圾回收。这个垃圾回收叫做Minor GC。年轻代被分为3个部分——Enden区和两个Survivor区。
  • 年轻代空间的要点:
  1. ⼤多数新建的对象都位于Eden区
  2. 当Eden区被对象填满时,就会执⾏Minor GC,并把所有存活下来的对象转移到其中⼀个survivor区
  3. Minor GC同样会检查存活下来的对象,并把它们转移到另⼀个survivor区。这样在⼀段时间内,总会有⼀个空的survivor区
  4. 经过多次GC周期后,仍然存活下来的对象会被转移到年⽼代内存空间,通常这是在年轻代有资格提升到年⽼代前通过设定年龄阈值来完成的。

年老代

  • 年⽼代内存⾥包含了⻓期存活的对象和经过多次Minor GC后依然存活下来的对象,通常会在⽼年代内存被占满时进⾏垃圾回收。

GC种类

  • Major GC&Full GC
  • ⽼年代的垃圾收集叫做Major GC,Major GC通常是跟full GC是等价的,收集整个GC堆。

jvisualvm堆栈溢出排查工具

  • 注:在jdk1.8下的bin文件中自带

模拟溢出错误

import java.util.ArrayList;
import java.util.List;
public class Test {
    private static final Integer K = 1024;
    public static void main(String[] args) {
        int size = K * K * 8;
        List<byte[]> list = new ArrayList<>();
        for(int i=0;i<K;i++){
            System.out.println("JVM写入数据"+(i+1)+"M");
            try{
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            list.add(new byte[size]);
        }
    }
}

分析

  • 可以看到不释放,堆空间就⼀直上去,直到OOM(out of memory)

在这里插入图片描述

  • 这个时候我们就dump下来堆信息看看
  • 会dump出⼀个这样的hprof快照⽂件,可以⽤jvisualvm本身的系统去分析,我这⾥推荐MAT
    在这里插入图片描述
    在这里插入图片描述
  • 你看他就是个暖男,都帮我们分析出来了⼀个问题,我们点进去看看
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

那怎么去服务器上jump呢?

jmap -dump:format=b,file=<dumpfile.hprof> <pid>
  • 不是所有的故障当时我们都在场的,⽆法及时jump,那也简单
-XX:+HeapDumpOnOutOfMemoryError
  • 配置这玩意之后,oom的时候会⾃动jump的,到时候拿快照分析⼀波就好了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值