您现在的位置是:首页 > 文章详情

jvm虚拟机中运行时数据区域介绍

日期:2019-06-11点击:327
 jvm虚拟机中,运行时数据区域包括七大部分 

_

 i. 程序计算器 i. 定义 1) 极小的内存空间; 2) 行号指示器,程序的分支、循环、跳转、异常处理、线程恢复等基本功能都需要依赖程序计算器; 3) 线程私有的。 ii. 由来 因为java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在一个确定的时刻,一个cpu只执行一条线程中的指令;为了线程切换后能 恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各线程之间计数器互不影响,独立存储,此内存为线程私有。 iii. 不同的使用场景 1) 线程执行的是java方法,计数器记录的是正在执行的虚拟机字节码指令的地址; 2) Native方法,计数器值为空; iv. 注意 在java虚拟机规范中唯一没有规定任何OutOfMemoryError情况的区域 ii. java虚拟机栈 i. 定义 1) 线程私有的,生命周期与线程相同; 2) 虚拟机栈描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息; 3) 方法的调用直至执行完成的过程,对应着栈帧在虚拟机栈中入栈到出栈的过程。 ii. 虚拟机栈主要的部分是局部变量表 1) 存放了编译器可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double-8 种)、对象引用和returnAddress类型(指向了一条字节码指令的地址); 2) 局部变量表所需的内存空间在编译期间完成分配,在方法运行期间不会改变局部变量表的大小; 3) 64位的long和double类型的数据占据2个局部变量空间。 iii. 两种异常 1) 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常; 2) 如果虚拟机可以动态扩展,如果扩展时无法申请到足够的内存,将会抛出OutOfMemoryErro异常。 iii. 本地方法栈 1) 与虚拟机栈作用类似,本地方法栈是虚拟机栈使用到的Native方法服务; 2) 在虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构没有强制规定,具体的虚拟机可以自由实现; 3) Sun HotSpot虚拟机把本地方法栈和虚拟机栈结合; 4) 本地方法栈也会报虚拟机栈的两种异常。 iv. java堆 i. 定义 1) java虚拟机管理的最大的一块内存; 2) 所有线程共享的内存区域; 3) 目的:存放对象实例,几乎所有的对象实例都在这里分配内存;(所有的对象实例以及数组都要在堆上分配) 4) 特别注意的是: 随着JIT编译器的发展与逃逸分析技术的成熟,栈上分配、标量替换优化技术带来了变化。 ii. 垃圾收集器 1) 垃圾收集的主要区域,也称为“GC堆”; 2) 从内存回收的角度:基本采用分代收集算法,一:java堆分为新生代和老年代;二:Eden空间、From Survivor空间、To Survivor空间等; 3) 从内存分配的角度:线程共享的java堆中可能划分出多个线程私有的分配缓冲区。目的是为了更好地、更快地回收内存; iii. 物理内存的划分 1) java虚拟机规范规定,java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可; 2) 实现时,即可是固定大小的,也可是可扩展的;当前主流的虚拟机都是可扩展的,通过-Xmx和-Xms控制; 3) 如果堆中没有内存,并且堆也无法扩展 ,抛出OutOfMemoryError异常。 v. 方法区 i. 定义 1) 所有线程共享的内存区域; 2) 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 ii. 方法区等于永久代? 1) 在HostSpot虚拟机中, 使用永久代来实现方法区,这样的话垃圾收集器可以像管理Java堆一样管理这部分内存; 2) 原则上,如何实现方法区属于虚拟机实现细节,不受虚拟机规范约束,使用永久代来是实现方法区是不合理的;因为容易出现内存溢出的问题; 3) Jdk1.7中,永久代中的字符串常量池中移出。 iii. 垃圾收集 1) 方法区和java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集; 2) 垃圾收集行为在方法区较少出现,方法区的内存回收目标主要是针对常量池的回收和对类型的卸载;(回收效果差,类型卸载要求高) 3) 回收非常有必要,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。 vi. 运行时常量池 i. 定义 1) 方法区的一部分; 2) 存放的是: 类加载后class文件中常量池的信息; 3) Class文件包括: 1 常量池 2 类的基本描述信息(字段、方法、接口) ii. 运行时常量池和Class文件中的常量池 1) 运行时常量池,细节要求不高,可以根据不同的需求来实现该内存区域; 2) Class包括其中的常量池,格式要求严格,具体到每一个字节存储的数据都必须符合才能被虚拟机认可、装载和执行; 3) 运行时常量池,不仅保存Class文件中描述的符号引用,而且也保存翻译的直接引用。 iii. 动态性 1) java语言并不要求常量一定只有编译器才能产生,也就是说不是只有提前放置在Class文件常量池中的内容才能进入方法区的运行时常量池; 2) 在运行期也可以将新的常量放入运行时常量池,比如String的intern()方法、 3) 常量池可能报OutOfMemoryError异常。 vii. 直接内存 i. 定义 1) Nio类,一种基于通道与缓存区的I/o方式,可以使用Native函数库直接分配堆外内存,通过存储在java堆中的DirectByteBuffer对象作为这块内存的引用; 2) Nio的使用在某些场合避免了在java堆和Native堆中来回复制数据,提高了性能; 3) 直接内存不受java堆大小的控制,但是受到本机总内存大小以及处理器寻址空间的限制; 4) 也是会报OutOfMemoryError异常。 参考: java虚拟机第二版
原文链接:https://yq.aliyun.com/articles/705128
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章