Java堆分析

内存溢出(OOM)的原因

在JVM中,有哪些内存区间?

1、堆:堆溢出
在这里插入图片描述
2、永久区溢出(perm)
在这里插入图片描述
3、线程栈:java栈溢出
在创建线程的时候,需要为线程分配栈空间,这个栈空间是向操作系统请求的,如果操作系统无法给出足够的空间,就会抛出OOM。
在这里插入图片描述
4、直接内存:直接内存溢出

  • ByteBuffer.allocateDirect()无法从操作系统获得足够的空间
    在这里插入图片描述

MAT使用

基于Eclipse的软甲,官网下载地址(http://www.eclipse.org/mat/ ),需要下载和JDK位数相同的。
在这里插入图片描述
在这里插入图片描述
在下图中,C是H的直接支配对象。当支配者被回收,被支配对象也被回收。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

浅堆

  • 一个对象结构所占用的内存大小
  • 在这里插入图片描述
    在这里插入图片描述
  • 3个int类型以及一个引用类型合计占用内存3*4 + 4=16个字节。再加上对象头的8个字节,因此String对象占用的空间,即浅堆的大小是16+8=24字节。
  • 对象大小按照8字节对齐
  • 浅堆大小和对象内容无关,只和对象结构有关。

深堆

  • 一个对象被GC回收后,可以真实释放的内存大小。
  • 只能通过对象访问到的(直接或者间接)所有对象的浅堆之和(支配树)
    示例:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    上图可以看到,所有的Point实例浅堆和深堆的大小都是16字节。而dLine对象,浅堆为16字节,深堆也是16字节,这是因为dLine对象内的两个点f和g没有被设置为null,因此,即使dLine被回收,f和g也不会被释放。对象cLine内的引用对象d和e由于仅在cLine内还存在引用,因此只要cLine被释放,d和e必然也作为垃圾被回收,即d和e在cLine的保留集内,因此cLine的深堆为16*2+16=48字节。

对于aLine和bLine对象,由于两者均持有对方的一个点,因此,当aLine被回收时,公共点a在bLine中依然有引用存在,故不会被回收,点a不在aLine对象的保留集中,因此aLine的深堆大小为16+16=32字节。对象bLine与aLine完全一致。

使用Visual VM分析堆

在这里插入图片描述
在这里插入图片描述
从类试图切换到实例试图,显示所有的实例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Tomcat OOM分析案例

1、Tomcat OOM

  • Tomcat在接收大量请求时发生OOM,获取Dump文件,进行分析。
  • 使用MAT打开堆。
  • 分析目的:
    1)找出OOM的原因
    2)推测系统OOM时的状态
    3)给出解决这个OOM的方法
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    OQL使用查询类情况。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    解决方法:
  • 1、OOM由于保存session过多引起,可以考虑增加堆大小。
  • 2、如果应用允许,缩短session的过期时间,使得session可以及时过期,并回收。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值