OutOfMemoryError分析-------思维导图

一、前言

  OutOfMemoryError是未检测异常的一个子类。在java程序运行时,JVM内存区域内除了程序计数器之外,其他区域都有可能抛出此异常。

JVM内存区域相关知识,见文章:《JVM虚拟机内存区域思维导图-------《深入理解Java虚拟机》2020第三版

  程序员往往需要根据OutOfMemoryError去定位具体是哪个内存区域出现了问题?是内存溢出还是内存泄漏? 只有问题定位准确,才能更好的修改、维护程序。因此,分析OutOfMemoryError很有实际意义。

二、思维导图

  笔者根据经典书籍《深入理解Java虚拟机》2020第三版,整理了一些常见的情况与处理方法,绘制了两张思维导图。
  两张图内容一样,只是展现形式不一样:第一张为鱼骨图;第二张为常见的树状图。读者可根据自己的喜好选择合适的格式阅读

1. OutOfMemoryError分析鱼骨图

在这里插入图片描述

2. OutOfMemoryError分析树状图

在这里插入图片描述

3. 内存涉及概念

在这里插入图片描述

三、 思维导图大纲

1. Java堆
1. 原因:对象创建过多,内存溢出;内存泄漏
2. 报错识别:从报错信息上,能明显看出发生在heap: java.lang.OutOfMemoryError: Java heap space
3. 深层分析:使用内存映像分析工具对Dump出来的 储存快照进行分析
4. 解决办法
	  + 内存泄漏
	    - 通过内存映像分析工具查看 泄漏对象到GC Roots的引用链
	    - 根据GC Roots引用链定位到 这些对象的创建位置,解决引用
	  + 内存溢出
	    - 修改JVM堆参数
	    - 加物理内存
5. 参数:-Xms/-Xmx
2. 栈stack
1. 单线程
	1). 原因:有些虚拟机选择不支持栈内存动态扩展; 或者栈内存因为物理内存或权限不够,无法动态扩展。 此时栈大小不够用时,会抛出OutOfMemoryError
	2). 报错识别:从报错信息上无法直接识别,只能看到是执行方法时报错了
	3). 特殊:Hotspot选择不支持栈内存动态扩展。它不会抛出 OutOfMemoryError,只会抛出StackOverflowError。 对Hotspot来说,"栈深"是动态变化的,并不是一个固定数值;  栈帧越大,栈深反而越小
	4). 参数:-Xss 注意此参数设置的是"栈容量"(20MB),而不是"栈深"(500层)
	5). 解决办法
		- 虚拟机参数,栈容量加大
		- 加物理内存
2. 多线程
    1). 原因:多线程会启动多个栈,多个栈会占用更多内存,这样有可能抛出OutOfMemoryError
	2). 报错识别:错误很明显  java.lang.OutOfMemoryError: unable to create native thread
	3). 解决办法
		- 减少线程启动数量
        - 增加物理内存
        - 更换64位虚拟机
        - 减少堆和减少栈容量,以换取更多线程
3. 方法区与常量池
1.	JDK6以前: 永久代
	1). 原因
        - 加载的类过多,方法区内存溢出
        - 常量过多,运行时常量池溢出
	2). 报错识别:java.lang.OutOfMemoryError: PermGen space
	3). 参数:-XX:PermSize/-XX:MaxPermSize
2.	JDK7以后: 元空间
	1). 原因
	    - 元空间使用本地内存,很难内存溢出
	    - 字符串常量池移到了堆Heap中,只会堆溢出
	2). 参数:-XX:MaxMetaspaceSize/-XX:MetaspaceSize
4. 本机直接内存溢出
1. 原因:通过某些方法获取本地直接内存太多,内存不够然后报错
2. 报错识别:错误不明显  java.lang.OutOfMemoryError, 栈路径中可以看到本地直接内存的调用API
3. 深层分析:Dump出来的储存快照文件很小,有直接或间接调用本地直接内存
4. 参数:-XX:MaxDirectMemorySize,如果不设置,则与-Xmx一致
5. StackOverflowError 分析
1.线程请求的栈深度大于虚拟机所允许的最大深度
2.JVM参数:-Xss,设置的是栈容量
3.抛出异常:java.lang.StackOverflowError,容易定位
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭Albert

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值