一、内存溢出(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. EntityFrameworkCore数据迁移(二)

    接上一篇 EntityFrameworkCore数据迁移(一) 其实上一篇该写的都已经写完了,但是后来又想到两个问题,想了想还是也写出来吧 问题一 上一篇介绍的迁移过程,都是通过在程序包管理器控制台使 ...

  2. 适配器模式(pthon)

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- # adapter_pattern.py # 适配器模式 class Adaptee: def reque ...

  3. JMeter_jmeter-plugins插件的安装使用

    一.安装JMter Plugins 1.官网下载 JMeter Plugins 的jar包 2. 将下载的jar包复制到 %JMETER_HOME%\lib\ext 目录下 3. 启动 JMeter ...

  4. i++ 和 ++i 区别

    i++:是先把i拿出来使用,然后再+1: ++i :是先把i+1,然后再拿出来使用:

  5. HIVE理论学习笔记

    概述 参加了新的公司新的工作新的环境之后,本人必须学习更多的知识,所以稳固之前的知识和学习新的知识是重中之重,新的公司把hadoop大部分的组件都进行了架构源码深度改造,所以使用过程确实遇到一些麻烦, ...

  6. 从AAB文件生成APK文件

    开头先说方法 1.下载 bundletool 2.开始生成 java -jar bundletool.jar build-apks --bundle=[aab文件路径(例如:C:\Users\Admi ...

  7. Python-多线程及生产者与消费者

    一.前置知识 1. 队列基础 如果不指定队列是什么,请自行查阅 在Python中,队列是最常用的线程间的通信方法,因为它是线程安全的 from queue import Queue # 创建队列 # ...

  8. 【机器学习】svm

    机器学习算法--SVM 目录 机器学习算法--SVM 1. 背景 2. SVM推导 2.1 几何间隔和函数间隔 2.2 SVM原问题 2.3 SVM对偶问题 2.4 SMO算法 2.4.1 更新公式 ...

  9. 解决windows下因为防火墙无法通过go get 下载gin的问题

    使用: go get -u github.com/gin-gonic/gin 出现以下错误: unrecognized import path "gopkg.in/yaml.v2" ...

  10. gin初识

    Gin 是一个用 Go (Golang) 编写的 web 框架. 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍. 如果你是性能和 ...