一.运行时数据区

  共分为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. [poj3250]单调栈 Bad Hair Day

    解题关键:将每头牛看到的牛头数总和转化为每头牛被看到的次数,然后用单调栈求解,其实做这道题的目的只是熟悉下单调栈 此题为递减栈 #include<cstdio> #include<c ...

  2. RecommenderFilterSalaryResult

    package org.andy.mymahout.recommendation.job; import java.io.BufferedReader; import java.io.File; im ...

  3. 2、perl模块查询安装否

    1.Perl 中每个包有一个单独的符号表,定义语法为:package mypack; 此语句定义一个名为 mypack 的包,在此后定义的所有变量和子程序的名字都存贮在该包关联的符号表中,直到遇到另一 ...

  4. 6.5 系统打开缓慢,怎么办?---更新Ubuntu系统

    早早的来公司打开电脑,希望看到Ubuntu能启动成功.可是,当我重启后,使用Ubuntu系统,打开界面速度非常慢,当时,又怀疑自己安装出错了.而且,6.2日Ubuntu系统的工作日志又没了.无奈,我把 ...

  5. 【Qt官方例程学习笔记】Address Book Example(代理模型)

    地址簿示例展示了如何使用代理模型在单个模型的数据上显示不同的视图. 本例提供了一个地址簿,允许按字母顺序将联系人分组为9组:ABC.DEF.GHI.…,VW,…XYZ.这是通过在同一个模型上使用多个视 ...

  6. C# 写 LeetCode easy #26 Remove Duplicates from Sorted Array

    26.Remove Duplicates from Sorted Array Given a sorted array nums, remove the duplicates in-place suc ...

  7. Note: Differentially Private Access Patterns for Searchable Symmetric Encryption

    The Core Issues and Ideas of This Paper Problem Baseline Searchable Symmetric Encryption (SSE) could ...

  8. Ajax的完整兼容各种浏览器版本代码

    <script type="text/javascript"> function createAjax(){ var request=false; //window对象 ...

  9. CodeForces 118C 【模拟】

    思路: 枚举0-9之间的数,然后判断. 然后一鼓作气打成了大模拟....我日啊... 心疼自己. #include <bits/stdc++.h> using namespace std; ...

  10. go培训课程都学什么?xorm框架学习系列(二):xorm结构体映射规则和表操作

    上节内容我们学习了基本的xorm框架的知识和基础配置的相关信息.本节课内容我们继续学习相关的知识和相关操作. 名称映射规则 名称映射规则主要负责结构体名称到表名和结构体field到表字段的名称映射. ...