一.运行时数据区

  共分为5块:

  • 程序计数器      (线程私有,当前线程所执行的字节码的行号指示器)
  • Java虚拟机栈  (线程私有,证明周期与线程相同,描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧,用于存储:局部变量表、操作数栈、动态链接、方法出口等信息)
  • 本地方法栈      (线程私有,本地方法栈类似于虚拟机栈,只不过执行的是Native方法)
  • Java堆         (线程共享的一块内存区域,几乎所有的对象实例以及数组都要在堆上分配)
  • 方法区              (线程共享,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据)
  • 直接内存         (并不属于JVM但是需要讲一下)

1.1  Java虚拟机栈
    
局部变量表: 存放了编译期可知的基本数据类型和对象引用和returnAddress类型。

  局部变量表所需的内存空间在编译期完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全正确的,在方法运行期间不会改变局部变量表的大小。

  在Java虚拟机规范中,对这个区域规定了两种异常情况:

  • 如果线程请求的栈深度大于虚拟机所允许的栈深度,将抛出StackOverflowError异常
  • 如果虚拟机可以动态扩展,扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常

 1.2  Java堆

   因为几乎所有的对象实例都要分配到堆上,而GC的主要清理目标就是对象实例,所以,Java堆是GC的主要区域。

   由于现在的收集器大都采用分代收集算法,所以Java堆还可以细分:新生代和老年代;再细致一点还可以分为Eden空间,from Survivor空间 和 to Survivor空间。

   具体 回收算法和方案  稍后 详细讲解

 

 1.3 对象的创建

  1. 检查这个new  指令的参数是否能够在常量池定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有则执行类加载。
  2. 为新生对象分配内存-指针碰撞: 堆内存是规整的,则只需要移动指针获取相应大小的空间;空闲列表:堆内存不规整,需要维护一个列表记录哪些内存空间可用,从列表中获取然后分配。会产生同步问题,CAS +失败重试机制。
  3. 内存分配完成之后,给内存空间初始化为零值(不含对象头)。
  4. 设置必要信息(属于哪个类的实例,类的元数据,对象的哈希码).
  5. 虚拟机部分对象已完成,接下来按照程序构造,初始化对象

二. OutOfMemoryError 和  StackOverflowError

    

1.java堆溢出  示例:

  配置参数:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError(dump当前内存堆的转储快照)

public class LeetCode {

    // 堆溢出
static class OOMobject {} public static void main(String[] args){
// 堆溢出
List<OOMobject> list = new ArrayList<>(); while(true){
list.add(new OOMobject());
} }
}

使用Jhat查看解析快照文件。

  解决方案:1.查看是否是内存泄露,可以用工具查看GC Roots与对象的关联路径  判断哪些对象是无用的,什么原因导致GC无法回收

       2.如不存在泄露,应当查看 堆参数 也就是 -Xmx 和 -Xms,看一下物理内存是否还允许堆内存调大一些

       3.从代码上检查是否存在某些对象的生命周期过长、持有状态时间过长的情况,尝试优化代码减少内存消耗。 

       

2.虚拟机栈溢出

public class LeetCode {

    private int stackLength = 1;

    public static void main(String[] args) throws Throwable{
LeetCode leetCode = new LeetCode();
try{
leetCode.stackLeak();
} catch (Throwable e) {
System.out.println("stack length:" + leetCode.stackLength);
throw e;
}
}
  public void stackLeak() {
  stackLength++;
   stackLeak();
  }
}

  使用 -Xss参数,减小栈的内存容量。结果抛出StackOverFlowError异常。

  

JVM(一):Java内存区域与内存溢出异常的更多相关文章

  1. JVM内存区域与内存溢出异常

    Java虚拟机在执行java程序时会把它所管理的内存会分为若干个不同的数据区域,不同的区域在内存不足时会抛出不同的异常. >>运行时数据区域的划分 (1)程序计数器程序计数器(Progra ...

  2. JVM基础知识(1)-JVM内存区域与内存溢出

    JVM基础知识(1)-JVM内存区域与内存溢出 0. 目录 什么是JVM 运行时数据区域 HotSpot虚拟机对象探秘 OutOfMemoryError异常 1. 什么是JVM 1.1. 什么是JVM ...

  3. 深入理解jvm之内存区域与内存溢出

    文章目录 1. Java内存区域与内存溢出异常 1.1. 运行时数据区域 1.1.1. 程序计数器 1.1.2. java虚拟机栈 1.1.3. 本地方法栈 1.1.4. Java堆(Java Hea ...

  4. 深入理解java虚拟机系列(一):java内存区域与内存溢出异常

    文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了開始.假设有什么错误或者遗漏,欢迎指出. 一.概述 先上 ...

  5. 深入理解java虚拟机---->java内存区域与内存溢出异常

    2. java内存区域于内存溢出异常 2.1 概述: 对于C/C++而言,内存管理具有最高的权利,既拥有每一个对象的“所有权”,又担负着每一个对象生命开始到结束的维护责任. 对于java而言,则把内存 ...

  6. 第二章Java内存区域与内存溢出异常

    第二章 Java内存区域与内存溢出异常 一.概述 对与Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每个new操作去写delete/free代码,不容易出现内存泄露和内存溢出问 题, ...

  7. 《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常

    第二章 Java内存区域与内存溢出异常 2.2 运行时数据区域  

  8. 深入了解Java虚拟机(1)java内存区域与内存溢出异常

    java内存区域与内存溢出异常 一.运行时数据区域 1.程序计数器:线程私有,用于存储当前所执行的指令位置 2.Java虚拟机栈:线程私有,描叙Java方法执行模型:执行方法时都会创建一个栈帧,存储局 ...

  9. 2.1 自动内存管理机制--Java内存区域与内存溢出异常

    自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存 ...

  10. 虚拟机--第二章java内存区域与内存溢出异常--(抄书)

    这是本人阅读周志明老师的<深入理解Java虚拟机>第二版抄写的,有很多省略,不适合直接阅读,需要阅读请出门左转淘宝,右转京东,支持周老师(侵权请联系删除) 第二章java内存区域与内存溢出 ...

随机推荐

  1. assert.strictEqual()

    assert.strictEqual(actual, expected[, message]) 使用全等运算符(===)测试 actual 参数与 expected 参数是否全等. // 格式 ass ...

  2. Ajax 执行流程 有用 一点

    l 1.1使用JavaScript获得浏览器内置的AJAX引擎(XMLHttpRequest对象) l 1.2 通过AJAX引擎确定请求路径和请求参数 l 1.3 通知AJAX引擎发送请求 l AJA ...

  3. Centos 查看机器型号

    测试机器的硬件信息: 查看CPU信息(型号) # cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 8 Intel(R) Xeon(R) CP ...

  4. Dockerfile设置apt-get install tzdata的noninteractive方法

    在Ubuntu系统中,执行命令apt-get install -y tzdata以安装tzdata软件包.但是,最近发现,在Ubuntu 18.04 (Bionic Beaver)上无法自动安装该软件 ...

  5. 32.我的wafBypass之道

    0x01 搞起 当我们遇到一个waf时,要确定是什么类型的?先来看看主流的这些waf,狗.盾.神. 锁.宝.卫士等等...(在测试时不要只在官网测试,因为存在版本差异导致规则库并不一致) 1.云waf ...

  6. 又见GCD (HDU 2504)

    这个题真的很水,但我竟然连错,在此警醒自己!!! 写代码改了东边,忘了西边,“认真”这两个字又被我吃了,打脸啪啪啪啪. #include<iostream> using namespace ...

  7. jQuery插件AjaxFileUpload可以实现ajax文件上传

    http://blog.sina.com.cn/s/blog_55e42da60100ocvh.html

  8. JetBrains Rider 自定义项目编译路径

    在项目开发过程中有时可能想要自定义 Rider 的编译输出路径,它的具体设置方式如下: 1.选择需要更改配置的项目,右键选择 Properties 菜单.   2.在 Configurations 菜 ...

  9. Unity3d 控制物体移动、旋转、缩放

    在Unity中通过利用 Input Manager(输入管理器)可以很简单的实现对一个物体进行移动.旋转.缩放操作. 演示代码: //通过虚拟轴控制物体移动.旋转.缩放 public class Mo ...

  10. libguestfs知识点

    libguestfs 是一组 Linux 下的 C 语言的 API ,用来访问虚拟机的磁盘映像文件.其项目主页是http://libguestfs.org/ , 该工具包内包含的工具有virt-cat ...