(学习笔记)jvm虚拟机模型
Java内存管理机制
java由于在虚拟机的自动管理机制下,可以不需要管理内存,提升了程序员跟多时间在业务逻辑中,但是对内存管理的封装,也导致了当出现内存泄露等问题时,修正问题是一个艰难的工作。
java运行时的数据区域
java所管理的内存将会按照以下几个区域进行划分:
-
程序计数器
程序计数器是一小块内存空间,其大小可以忽略不计,他是程序控制流的指示器,分支,循环,跳转,异常处理,县城回复等基础功能都需要依赖这个计数器。
在多线程中,由于在某个时刻,一个处理器(或者一个内核)都只会执行一个线程,因此为了线程切换后可以回复到正确的位置。
每个线程有独力的计数器,互不影响,独立存储,我们将这类内存区域称之为线程私有的内存。 -
Java 虚拟机栈
与程序计数器一样,虚拟机栈也是线程私有的,生命周期与线程相同。
虚拟机栈的生命周期与县城乡同,描述的java方法被执行的线程内存模型:每个方法被执行的时候mjava虚拟机都会同步创建一个栈帧,用于存储局部吧变量表、操作数栈、动态连接、方法出口等信息,一个虚拟机调用方法并执行完毕,对应着一个栈帧在虚拟机栈中入栈到出站的过程。
局部变量表主要存放的是java的基本数据类型(boolean,byte、char、short、int、float、double、),对象引用(reference)与 returnAddress类型。
这些局部变量在局部变量表中的存储空间用局部变量槽表示。
-虚拟机栈中出现的两种异常:
1 线程请求的栈深度大于虚拟机允许深度,抛出StackOverflowError
2 虚拟机栈容量可以动态扩展,但是扩展是无法扩展时抛出OOM异常。 -
本地方法栈
本地方法栈与虚拟机栈功能类似,到那时虚拟机栈中执行的是java的方法,本地方法栈执行的是本地(Native)方法。 -
java堆
java 是虚拟机中内存管理中最大的一块,是所有线程共享的一块内存区域,在虚拟机启动时创建,java中“几乎”所有的对象实例都在堆中。
java堆是垃圾收集器管理的内存区域,GC堆。(以前,不少书中仍然人物java的堆内存分为新生代,老年代,永久代,等)
java堆可以划出多个线程私有的分配缓冲区(TLAB)提高分配效率。
java堆可以出现于不连续的物理上的内存空间中,但是其逻辑上是连续的。
主流的虚拟机堆是通过(-Xmx 与-Xms)大小的。如果堆中内衣实例分配,或者堆无法继续扩展时,将会抛出oom异常。 -
方法区
方法区与java堆一样,都是线程共享的内存区域,用于储存加载的类型信息,常量,静态常量,及时编译器编译后的代码缓存等数据。
方法区无法满足新的内存分配需求时,将抛出oom异常。 -
运行时常量池
运行时常量池是方法区的一部分,class文件中除了有类的版本、字段、方法、还有一个是常量池表,用于存放编译期生成的各种字面量与符号引用。
运行是常量池中北使用较多的是String的intern()方法,因为,通过String s=“xxx”赋值的s是首先在运行时常量池中查找是否有“xxx”,如果没有则创建一个空间来储存,如果有则直接在栈内存中开辟一个s的空间,来存储“xxx”的地址。
而通过new String(“xxx”)的方法是直接在堆中创建的对象。
运行时常量池是方法区的一部分自然收到方法区内存限制 ,无法申请内存是抛出oom异常。
HotSpot虚拟机对象揭秘
- 对象的创建
当虚拟机遇到一条字节码的new命令时,首先将去检查这个指令是否以及在常量池中 可以定位到一个类的符号引用,并且检查引用带边的类是否被加载、解析与初始化过。如果没有,就将执行相应的类加载过程。
类检查通过后将进行给新生的对象分配内存,内存的大小在类加载后就可以确定。就是将一块确定大小的内存从java堆中划分出来。采用指针碰撞的方式。 - 解决对线创建在并发情况下的线程安全,通过的是两个方法
(1)对分配的内存空间动作进行同步处理--实际上虚拟机采用的是CAS配上失败重试的方式来保证更新操作的原子性的。
(2) 另外一个是将内存分配的动作按照线程划分为不同的空间进行,预分配空间给每个线程,即本地缓冲区(TLAB)。
- 内存分配完毕后将初始化零值
- 对象的创建内存布局
对象可以划分为三个部分,对象头,实例数据,对其填充。
HotSpot虚拟机对象的对象头包括两类信息:
(1) 是储存对象自身运行时数据,汝hashCode、GC分带年龄、锁状态的标志等。
(2) 另外一部分是类型指针,通过指针来确定该对线是哪个类的实例。 - 对象的访问定位
对象的访问方式有句柄访问与直接指针两种。
(1) 句柄访问时在java堆中划分出一块内存做句柄池,referecne是对象的句柄地址,句柄中包含对线的实例数据与类型数据各自的地址。
(2) 直接指针是referece中储存的直接是对线的地址,减少一次访问开销。
(图片转自https://blog.csdn.net/qq_41901915/article/details/88956143)