JVM内存区域划分(JDK6/7/8中的变化)
前言
Java程序的运行是通过Java虚拟机来实现的。通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行。Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些内存区域被统一叫做运行时数据区。Java运行时数据区大致可以划分为5个部分。如下图所示。在这里要特别指出,我们现在说的JVM内存划分是概念模型。具体到每个JVM的具体实现可能会有所不同。具体JVM的实现我只会提到HotSpot虚拟机的实现细节。
程序计数器
程序计数器是一块较小的内存空间,它可以看成是当前线程所执行的字节码的行号指示器。程序计数器记录线程当前要执行的下一条字节码指令的地址。由于Java是多线程的,所以为了多线程之间的切换与恢复,每一个线程都需要单独的程序计数器,各线程之间互不影响。这类内存区域被称为“线程私有”的内存区域。
由于程序计数器只存储一个字节码指令地址,故此内存区域没有规定任何OutOfMemoryError情况。
虚拟机栈
Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
一个栈帧就代表了一个方法执行的内存模型,虚拟机栈中存储的就是当前执行的所有方法的栈帧(包括正在执行的和等待执行的)。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。我们平时所说的“局部变量存储在栈中”就是指方法中的局部变量存储在代表该方法的栈帧的局部变量表中。而方法的执行正是从局部变量表中获取数据,放至操作数栈上,然后在操作数栈上进行运算,再将运算结果放入局部变量表中,最后将操作数栈顶的数据返回给方法的调用者的过程。(关于栈帧和基于栈的方法执行,我会在之后写两篇文章专门介绍。敬请期待☺)
虚拟机栈可能出现两种异常:由线程请求的栈深度过大超出虚拟机所允许的深度而引起的StackOverflowError异常;以及由虚拟机栈无法提供足够的内存而引起的OutOfMemoryError异常。
本地方法栈
本地方法栈与虚拟机栈类似,他们的区别在于:本地方法栈用于执行本地方法(Native方法);虚拟机栈用于执行普通的Java方法。在HotSpot虚拟机中,就将本地方法栈与虚拟机栈做在了一起。
本地方法栈可能抛出的异常同虚拟机栈一样。
堆
Java堆是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例:所有的对象实例以及数组都要在堆上分配(The heap is the runtime data area from which memory for all class instances and arrays is allocated)。但Class对象比较特殊,它虽然是对象,但是存放在方法区里。在下面的方法区一节会介绍。Java堆是垃圾收集器(GC)管理的主要区域。现在的收集器基本都采用分代收集算法:新生代和老年代。而对于不同的”代“采用的垃圾回收算法也不一样。一般新生代使用复制算法;老年代使用标记整理算法。对于不同的”代“,一般使用不同的垃圾收集器,新生代垃圾收集器和老年代垃圾收集器配合工作。(关于垃圾收集算法、垃圾收集器以及堆中具体的分代等知识,我之后会专门写几篇博客来介绍。再次敬请期待☺)
Java堆可以是物理上不连续的内存空间,只要逻辑上连续即可。Java堆可能抛出OutOfMemoryError异常。
方法区
方法区与Java堆一样,是各个线程共享的内存区域。它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
所有的字节码被加载之后,字节码中的信息:类信息、类中的方法信息、常量信息、类中的静态变量等都会存放在方法区。正如其名字一样:方法区中存放的就是类和方法的所有信息。此外,如果一个类被加载了,就会在方法区生成一个代表该类的Class对象(唯一一种不在堆上生成的对象实例)该对象将作为程序访问方法区中该类的信息的外部接口。有了该对象的存在,才有了反射的实现。
在Java7之前,HotSpot虚拟机中将GC分代收集扩展到了方法区,使用永久代来实现了方法区。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载。但是在之后的HotSpot虚拟机实现中,逐渐开始将方法区从永久代移除。Java7中已经将运行时常量池从永久代移除,在Java 堆(Heap)中开辟了一块区域存放运行时常量池。而在Java8中,已经彻底没有了永久代,将方法区直接放在一个与堆不相连的本地内存区域,这个区域被叫做元空间。
关于元空间的更多信息,请参考:Java永久代去哪儿了
运行时常量池
运行时常量池是方法区的一部分,关于运行时常量池的介绍,请参考我的另一篇博文:String放入运行时常量池的时机与String.intern()方法解惑。我还是花了些时间在理解运行时常量池上的。
直接内存
JDK1.4中引用了NIO,并引用了Channel与Buffer,可以使用Native函数库直接分配堆外内存,并通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。
如上文介绍的:Java8以及之后的版本中方法区已经从原来的JVM运行时数据区中被开辟到了一个称作元空间的直接内存区域。
参考:
《深入理解Java虚拟机-JVM高级特性与最佳实践》第二版 周志明著
JVM内存区域划分(JDK6/7/8中的变化)的更多相关文章
- JVM内存区域划分及垃圾回收
第一部分.闲扯+概述 近来在研读<深入理解java虚拟机>一书,读完之后做个小结,算是记录一下自己的学习所得,在成长的路上,只能死磕. 要理解JVM,就要先从其内存区域划分开始,知道其由几 ...
- JVM内存区域划分
前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同 ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
以下内容转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29632145&id=4616836 jvm区域总体分两 ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释(转)
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM内存区域划分Eden Space,Survivor Space,Tenured Gen,Perm Gen
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM内存区域划分总结
发现网上有两个版本的JVM内存划分,一个是按照<深入理解JVM虚拟机>上的版本,包含程序计数器等,按照是否线程共享划分. 另一个我觉得更好记一些,也更适合我自己,在这里记录一下. 首先上思 ...
- [转]JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM 内存区域划分
一.运行时数据区包括哪几部分? 根据<Java虚拟机规范>的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register).Java栈(VM Stac ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释 (生动形象)
[转自]:https://blog.csdn.net/sd4015700/article/details/50109939 jvm区域总体分两类,heap区和非heap区.heap区又分:Eden S ...
随机推荐
- VueJs 源码解析 (四) initRender.Js
vueJs 源码解析 (四) initRender.Js 在之前的文章中提到了 vuejs 源码中的 架构部分,以及 谈论到了 vue 源码三要素 vm.compiler.watcher 这三要素,那 ...
- [C#]Google Chrome 书签导出并生成 MHTML 文件
目的 因为某些原因需要将存放在 Google Chrome 内的书签导出到本地,所幸 Google Chrome 提供了导出书签的功能. 分析 首先在 Google Chrome 浏览器当中输入 ch ...
- Shiro加密
在开发的时候,很多数据我们都希望是以加密过后的形式存储起来,而不是最原始的数据. 在shiro中也提供了编码,解码,加密,加密算法实现等等一系列的内容. 编码/解码 在org.apache.shiro ...
- [Tjoi 2013]松鼠聚会
3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1318 Solved: 664[Submit][Stat ...
- 【网络流】【BZOJ1061】【NOI2008】志愿者招募
原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1061 题意:问你如何购买志愿者使得满足题意的总费用最小. 解题思路:首先,由于志愿者存在的 ...
- [BZOJ]1003 物流运输(ZJOI2006)
挖坑,日常划水. 从BZOJ上的AC人数来看这题确实不难,但做这种题的常见思路让小C决定还是mark一下. Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才 ...
- bzoj1043[HAOI2008]下落的圆盘 计算几何
1043: [HAOI2008]下落的圆盘 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1598 Solved: 676[Submit][Stat ...
- bzoj1094[ZJOI2007]粒子运动 计算几何
1094: [ZJOI2007]粒子运动 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 658 Solved: 164[Submit][Status ...
- String.IndexOf 方法笔记
记录以备使用 作用:报告指定 Unicode 字符或字符串在此实例中的第一个匹配项的从零开始的索引. 如果未在此实例中找到该字符或字符串,则此方法返回 -1. 重载列表 名称 说明 IndexOf ...
- 在腾讯云的ubuntu服务器上面安装git服务器
GitHub是一个免费托管开源代码的远程仓库.但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用.搭建Git服 ...