java内存区域详解

以下内容参考自《深入理解 java虚拟机 JVM高级特性与最佳实践》,其中图片大多取自网络与本书,以供学习和参考。

一、运行时数据区域

异常解释:StackOverflowError是指线程请求的栈深度大于虚拟机所允许的深度时所抛出的异常;OutOfMemoryError是指扩展时无法申请到足够的内存时所抛出的异常。

线程安全:

1.程序计数器:当前线程所执行的字节码的行号指示器,字节码解释器通过改变计数器值来读下一条需要执行的字节码指令,如果线程执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined),是唯一没有规定OutOfMemoryError的区域。

2.java虚拟机栈:每个方法被执行时会同时创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口,方法调用的过程就是栈帧从入栈到出栈的过程。大多程序员所关注的栈内存,就是指的虚拟机栈中的局部变量表部分,其内存放了编译期可知的基本数据类型、对象引用(reference类型)和returnAddress类型(返回值类型),会抛StackOverflowError和OutOfMemoryError。见下图:

详细介绍请参考此网页:http://blog.csdn.net/zq602316498/article/details/38926607

3.本地方法栈:与虚拟机栈功能类似,区别:虚拟机栈为虚拟机执行java方法服务,而本地方法栈为Native方法服务。同样抛StackOverflowEror和OutOfMemoryError。

4.直接内存:不是虚拟机运行时数据区的一部分,NIO类可以使用Native函数库直接分配堆外内存,然后通过一个存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。避免了在java堆和Native堆中来回复制数据。直接内存会受到本机总内存大小及处理器寻址空间的限制。因此也会有OutOfMemoryError异常。

线程共享:

5.java堆(GC 堆):唯一目的是存放对象实例。是GC的主要区域,所以被称作“GC 堆”,堆可以被细分为:“新生代”和“老年代”会抛OutOfMemoryError。

6.方法区(非堆):存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。和堆一样内存可以不连续且大小可扩展或固定。这区域的内存回收目标主要是针对常量池的回收和对类型的卸载,GC回收的条件苛刻,会抛OutOfMemoryError。

7.运行时常量池:运行时常量池是方法区的一部分,Class文件(字节码文件)中有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容在类加载后进入方法区的运行时常量池存放,翻译出来的直接引用也存储在其中,具备动态性,运行期间也可将常量放入池中,例如String类的intern()方法,会抛OutOfMemoryError异常。

★常量池:Class文件中存储的信息。 运行时常量池:运行时常量池是随java虚拟机启动而被创建的。

运行时常量池是把Class文件常量池加载进来,每个类有一个独立的。刚开始运行时常量池里的链接都是符号链接,跟在Class文件里一样;边运行边就会把用到的常量转换成直接链接,例如说要Class A调用Foo.bar()方法,A.class文件里就会有对该方法的Methodref常量,是个符号链接(只有名字没有实体),加载到运行时常量池也还是一样是符号链接,等真的要调用该方法的时候该常量就会被resolve为一个直接链接(直接指向要调用的方法的实体)。

二、HotSpot虚拟机对象探秘

1.查看java虚拟机

运行cmd 2.输入java -version命令,见下图,可知运行的是HotSpot VM,这是JDK自带的虚拟机。

2.对象的创建

(1)虚拟机在遇到一条new指令时,先检查指令能否在常量池中定位到类的符号引用,并检查该类是否被加载、解析和初始化过,如果没有则执行相应的类加载过程,加载-验证-准备-解析-初始化。(2)虚拟机为新生对象分配内存。对象的内存在类加载完成后即可完全确定。分配java堆内存的方式有“指针碰撞”(带Compact过程的收集器)和“空闲列表”(基于Mark-Sweep算法的收集器)两种,选择哪种方式由java堆是否规整而决定的。(3)创建对象时的分配内存存在线程安全问题,其解决办法有两种,一种是对分配内存空间的动作进行同步处理;另一种是每个线程在java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB)。

3.对象的内存布局

在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头、实例数据和对齐填充(HotSpot VM要求对象大小必须是8的整数倍,而对象头正好是8的倍数,因此当对象实例数据部分没有对齐时,需要通过对齐填充来补全)。

4.对象的访问定位

使用对象是通过栈上的reference数据来操作堆上的具体对象的,对象访问的方式取决于虚拟机实现而定。目前主流的访问方式有使用句柄和直接指针两种。

(1)通过句柄访问对象

(2)通过直接指针访问对象

三、异常实战

1.java堆溢出

2.虚拟机栈和本地方法栈溢出

3.方法区和运行时常量池溢出

4.本机直接内存溢出

《深入理解 java虚拟机》学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

  10. ucos实时操作系统学习笔记——任务间通信(消息)

    ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...

随机推荐

  1. Daily Scrum Meeting ——FourthDay(Beta)12.12

    一.Daily Scrum Meeting照片 讨论界面优化详情 二.Burndown Chart 项目有条不紊地进行中... 1.新增6个界面修改计划 2.修复两个BUG 三.项目进展(check- ...

  2. 北京电子科技学院(BESTI)实验报告4

    北京电子科技学院(BESTI)实验报告4 课程: 信息安全系统设计基础 班级:1452.1453 姓名:(按贡献大小排名)周恩德 .郑凯杰 学号:(按贡献大小排名)20145217 .201453 指 ...

  3. Holographic Remoting

    看到微软官方的 Holographic Remoting Player https://developer.microsoft.com/en-us/windows/holographic/hologr ...

  4. SOAPUI使用教程-测试JDBC数据库

    soapUI中有除了开源版本的一些非常实用的功能: 使用在项目级配置的JDBC连接 使用向导创建复杂的查询. 结果显示XML输出视图(以及该使用向导在此视图中提供的XPath断言). 提供JDBC连接 ...

  5. acm入门 杭电1001题 有关溢出的考虑

    最近在尝试做acm试题,刚刚是1001题就把我困住了,这是题目: Problem Description In this problem, your task is to calculate SUM( ...

  6. LintCode 78:Longest Common Prefix

      public class Solution { /** * @param strs: A list of strings * @return: The longest common prefix ...

  7. Ajax完整篇(转载)

    Ajax 完整教程 第 1 页 Ajax 简介Ajax 由 HTML.JavaScript™ 技术.DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用 ...

  8. 使用spring的@Scheduled注解执行定时任务,启动项目不输出警告

    在applicationContext.xml中添加: xmlns:task="http://www.springframework.org/schema/task" xsi:sc ...

  9. 使用Jmeter录制web脚本

    1:启动Jmeter: 2:选择测试计划,右键->添加->Threads(users)>线程组 3:选择这个线程组,右键->添加->配置元件->HTTP请求默认值, ...

  10. OpenSSL 1.0.2e 3 Dec 2015

    目录: 1,交叉编译openssl 2,win32  vc9 编译 openssl 1,交叉编译openssl [原]交叉编译openssl不修改Makefile的方法 http://blog.chi ...