一、内存溢出(OOM)的原因

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

堆溢出
public static void main(String args[]){
ArrayList<byte[]> list=new ArrayList<byte[]>();
for(int i=0;i<1024;i++){
list.add(new byte[1024*1024]);
}
}

永久区
生成大量的类
public static void main(String[] args) {
for(int i=0;i<100000;i++){
CglibBean bean = new CglibBean("geym.jvm.ch3.perm.bean"+i,new HashMap());
}
}

Java栈溢出

这里的栈溢出指,在创建线程的时候,需要为线程分配栈空间,这个栈空间是向操作系统请求的,如果操作系统无法给出足够的空间,就会抛出OOM

public static class SleepThread implements Runnable{
public void run(){
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String args[]){
for(int i=0;i<1000;i++){
new Thread(new SleepThread(),"Thread"+i).start();
System.out.println("Thread"+i+" created");
}
}

直接内存溢出
ByteBuffer.allocateDirect()无法从操作系统获得足够的空间

for(int i=0;i<1024;i++){
ByteBuffer.allocateDirect(1024*1024);
System.out.println(i);
System.gc();
}

二、MAT使用基础

浅堆(Shallow Heap)与深堆(Retained Heap)
显示入引用(incoming)和出引用(outgoing)
支配树

nMemory Analyzer(MAT)
n基于Eclipse的软件
nhttp://www.eclipse.org/mat/
 

                                       

浅堆
一个对象结构所占用的内存大小
 

–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分析堆

– java自带的多功能分析工具,可以用来分析堆Dump

类的柱状图 ,显示对象数量,总大小等:

从类试图切换到实例试图,显示所有的实例:

使用OQL查询:

返回引用了(0,0)这个点的所有对象

四、Tomcat OOM分析案例

Tomcat 在接收大量请求时发生OOM,获取堆Dump文件,进行分析。

如果是session过多引起OOM

–  OOM由于保存session过多引起,可以考虑增加堆大小

–  如果应用允许,缩短session的过期时间,使得session可以及时过期,并回收

原文:https://www.cnblogs.com/pony1223/p/9206715.html

JVM学习六:堆分析的更多相关文章

  1. 深入理解JVM一java堆分析

    上一节介绍了针对JVM的监控工具,包括JPS可以查看当前所有的java进程,jstack查看线程栈可以帮助你分析是否有死锁等情况,jmap可以导出java堆文件在MAT工具上进行分析等等.这些工具都非 ...

  2. JVM学习笔记——堆

    堆 Heap 一个 JVM 只有一个堆,堆也是 Java 内存管理的核心区域.在 JVM 启动时堆被创建,同时大小在启动时已设定好,堆是 JVM 管理最大的一块内存空间,其大小可以调节. 堆的内存空间 ...

  3. JVM学习--(六)类加载器原理

    我们知道我们编写的java代码,会经过编译器编译成字节码文件(class文件),再把字节码文件装载到JVM中,映射到各个内存区域中,我们的程序就可以在内存中运行了.那么字节码文件是怎样装载到JVM中的 ...

  4. JVM学习之实例分析JVM安全体系

    转自:http://www.importnew.com/17093.html,感谢分享 类加载器的作用就是将真实的class文件根据位置将该Java类的字节码装入内存,并生成对应的Class对象.用户 ...

  5. JVM学习之堆和栈

    Java栈与堆 1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快, ...

  6. JVM学习六:JVM之类加载器之双亲委派机制

    前面我们知道类加载有系统自带的3种加载器,也有自定义的加载器,那么这些加载器之间的关系是什么,已经在加载类的时候,谁去加载呢?这节,我们将进行讲解. 一.双亲委派机制 JVM的ClassLoader采 ...

  7. JVM学习十三:JVM之堆分析

    本章进入JVM学习的最后一节,此节主要分析的是堆,因为堆是JAVA程序中最常用使用到的地方,因此对这个地方有必要进行下细致的分析特别是OOM,言归正传,进入正文. 一.内存溢出(OOM)的原因 在JV ...

  8. JVM学习--(八)java堆分析

    上一节介绍了针对JVM的监控工具,包括JPS可以查看当前所有的java进程,jstack查看线程栈可以帮助你分析是否有死锁等情况,jmap可以导出java堆文件在MAT工具上进行分析等等.这些工具都非 ...

  9. JVM内核-原理、诊断与优化学习笔记(八):JAVA堆分析

    文章目录 内存溢出(OOM)的原因 在JVM中,有哪些内存区间? 堆溢出 永久区 Java栈溢出 直接内存溢出 小问题? MAT使用基础 柱状图显示 支配树 显示线程信息 显示堆总体信息,比如消耗最大 ...

随机推荐

  1. 基于Spring MVC + Spring + MyBatis的【医院就诊挂号系统】

    资源下载:https://download.csdn.net/download/weixin_44893902/21727306 一.语言和环境 1.实现语言: JAVA语言. 2.环境要求: MyE ...

  2. 使用 DDL 语句分别创建仓库表、供应商表、产品表和入库表,并对其进行操作

    查看本章节 查看作业目录 需求说明: 使用 DDL 语句分别创建仓库表.供应商表.产品表和入库表 使用 DML 语句分别新增一条仓库表.供应商表.产品表和入库表记录 使用 DML 语句更新满足指定条件 ...

  3. Java面向对象笔记 • 【第3章 继承与多态】

    全部章节   >>>> 本章目录 3.1 包 3.1.1 自定义包 3.1.2 包的导入 3.1.3 包的访问权限 3.1.4 实践练习 3.2 继承 3.2.1 继承概述 3 ...

  4. 显示器接口VGA、DVI、HDMI、DP

    1.说明 对于显示器接口类型, 常见的接口有VGA.DVI.HDMI.DP这四种, 当然还有其他类型接口, 本文主要介绍上面四种接口, 介绍接口的基本规格参数和外形等, 以及这四种接口之间的联系和区别 ...

  5. 【17MKH】我在框架中对.Net依赖注入的扩展

    说明 依赖注入(DI)是控制反转(IoC)的一种技术实现,它应该算是.Net中最核心,也是最基本的一个功能.但是官方只是实现了基本的功能和扩展方法,而我呢,在自己的框架 https://github. ...

  6. CSS基础 元素整体透明效果(包含内容+背景及子元素)

    属性名:opacity:数字+px; 数字值取值0-1之间数字 数字值:1表示完全不透明 0表示完全透明使用后效果 html结构代码 <div class="box"> ...

  7. 关于java的Excel导入导出之easypoi

    导入easypoi相关jar包,这里的easypoi-base的包也可以不倒入,因为easypoi-web中有依赖easypoi-base会自动导入的 <!-- https://mvnrepos ...

  8. 初识python: 回调函数

    回调函数 简单理解就是:将一个函数通过参数的形式传递给另一个函数 #!/user/bin env python # author:Simple-Sir # time:2019/8/9 10:49 # ...

  9. Flask_路由(二)

    一.路由规则设置说明 flask框架使用route()装饰器配置路由. from flask import Flask app = Flask(__name__) @app.route("/ ...

  10. mybatis-plus实现多表联查

    一.方法一 1.在pojo模块下新建一个VO 包路径用于提供页面展示所需的数据 2.在vo包下新建EmployInfo类,此类继承了Employees类,再把Dept类的数据复制过来 3.在Dao层中 ...