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. jquery插件开发

    jQuery是一个封装的很好的类,比如我们用语句$("#btn1") 会生成一个 jQuery类的实例. 一.jQuery插件开发注意要点 1.使用闭包,避免全局依赖,避免第三方破 ...

  2. LNMP虚拟机开发环境配置--vagrant+virtualbox+ubuntu14.04

    工作一直用的是别人打包好的虚拟机开发环境,感觉确实很酷.所以准备自己配个开发环境,为之后自己开发一些有趣的东西做准备. ok,开始~~~ 一.安装软件 vagrant和virtualbox 此处需注意 ...

  3. sql server的优缺点

    sql server的优点众多,让其在数据库领域独占鳌头,成为最受欢迎的数据库系统,其优缺点也自然是喜爱者们所关注的,首先了解一下它的历史: sql server是一个关系型数据库管理系统,最初是由M ...

  4. Python开发工具PyCharm个性化设置(图解)

    Python开发工具PyCharm个性化设置,包括设置默认PyCharm解析器.设置缩进符为制表符.设置IDE皮肤主题等,大家参考使用吧. JetBrains PyCharm Pro 4.5.3 中文 ...

  5. 谷歌浏览器如何查看或获取Cookie字符串

    注:此博客仅供非web开发人员查看,以下内容都基于谷歌浏览器. 在网页空白处点击鼠标右键,在弹出菜单中选择[审查元素],可以看到网页下方出现审查元素相关界面. 在审查元素相关界面,点击[Network ...

  6. git上传代码到osc@git

    1.get an account 2.get a ssh-key 3.git setting git config --global user.name "...." git co ...

  7. C,C++

    C与C++的Struct有何区别,Java有Struct吗,C++里Struct与Class区别: C++虚析构函数作用: static静态变量初始化: 深复制与浅复制区别: const * int ...

  8. 自定义委托类型 - .Net自带委托类型

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递. 与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用. 一.自定义委托类型 1.语法结构:访问修 ...

  9. ajax 后台正常执行 错误类型却是404

    后台执行importExcel,明明方法执行成功,但是前台却提示404 @RequestMapping("/import") public Json importExcel(@Re ...

  10. 学习angular2

    最近在学angular2,并没有很深入,跟着官网做了一份练习,整理了一下,画了一个简单的结构图.