JVM内存模型-入门到精通

1、JVM内存模型主要分为两类,线程共享和线程私有。
线程共享:方法区、堆
线程私有:程序计数器、虚拟机栈、本地方法栈
 
方法区:线程共享的内存区域,主要存放类信息,常量,静态变量。其中运行时常量池(常量池)也是在方法区内,常量池中主要存放字面量和符号引用
 
:JVM管理内存的最大一块内存空间,存放实例对象、数组。线程私有缓冲区(TALB)也是在堆上面的,但和堆内存互不影响。在随着JIT编译器的发展,并不是所有实例对象和数组一定是存放在堆内存上面。参考(逃逸分析、栈上分配、标量替换)优化技术。
 
程序计数器:线程的字节码执行的行号指示器,用来记录线程下一步的执行指令。字节码解释器会根据程序计数器中的值来获取线程下一条执行指令,也是整个内存空间中唯一一个不会抛出OOM异常的内存区域。
 
虚拟机栈:虚拟机栈也就是我们常说的栈内存,主要存放局部变量表、操作栈帧、动态链接、方法出口等信息。局部变量表中存放基础类型数据,对象引用,其中long和double类型占两个局部变量空间,其余类型占一个局部变量空间。
 
本地方法栈:本地方法栈中存什么我也不知道,(⊙o⊙)…如果面试被问到我觉得那个人脑子有问题......存储的内容没有强制规定,有虚拟机自由实现。主要是为虚拟机调用native方法服务的。
 
 
JVM内存模型中,除了程序计数器外其余内存空间都会抛出OOM异常。其中栈内存还会抛出StackOverflowError异常。
 
 
 
 
2、 JVM创建对象过程
 
使用new关键字来实例化一个对象的时候,JVM会去常量表中定位到这个类的符号引用,然后会去检查这个符号引用所代表的类有没有被加载、分析、初始化过,如果没有,则启动类加载器来加载,执行相应的类加载过程。然后在堆内存上开辟一块空间,优先在新生代的Eden区域开辟,由于在类加载编译过程中,类的内存空间大小已经是预知的,所以根据预知的空间大小来开辟。如果Eden区域没有相应的空间大小,则向后移动内存空间区域(指的时Survivor或者老年代内存区域)。如果还是没有内存区域,则执行垃圾回收器进行内存回收,如果垃圾回收器回收后依然没有足够的内存空间(这里的垃圾回收器指的时CMS或者G1),则执行Full GC,如果还是没有,则抛出OOM异常,实例化对象失败。划分内存的方式有两种,一种是指针碰撞,一种是空闲列表,至于采用何种方式,取决于GC的类型。为了避免多线程并发的安全问题,JVM提供两种解决方式,一种是CAS操作加失败重试机制,另外一种是把内存按线程来划分到不同的内存空间,即本地线程缓冲区(TALB)。创建好对象以后,进行初始化,默认值都为零,在JVM的角度看来,对象已经创建成功,但是在程序角度看来,对象还未创建成功,才刚刚开始,接下去会执行初始化方法,进行对象初始化。完成真正意义上的对象创建
 
3、 对象的内存布局
对象存储的布局可以分为3快空间, 对象头实例数据填充对齐
对象头:对象头包含两部分, 第一部分Mark Work,用于存储对象自身信息,例如hash code,GC分代年龄,锁状态标志、线程持有的锁、偏向线程ID、偏向锁时间戳等,如果对象是一个JAVA数组,那么对象头中还有一块用于存储数组长度的数据。
第二部分为类型指针,指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
第二部分:实例数据部分是对象真正存储的有效信息,也就是程序代码中定义的各种类型的字段信息。无论父类还是子类信息,都会记录下来。这部分存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)和字段在JAVA源码中定义顺序的影响。
第三部分:填充对齐...不做过多解释,自己查资料。
 
4、对象的访问定位
栈内存上的reference数据是指向对象的引用,目前主流的访问方式有两种, 句柄直接指针
句柄:在JAVA堆内存上划分出一块内存做为句柄池,reference数据中存储的就是对象在句柄池中的地址,而在句柄中包含了对象的实例数据和类型数据地址,分别指向实例池和方法区的对象类型数据。
直接指针:直接存放实例对象的地址。而java堆对象一部分存储了对象实例数据,另外一部分存储了对象类型数据。
 
 
 
 
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM(Java虚拟机)模型是指Java程序在运行时的执行环境,包括JVM的组成部分和它们的工作原理。JVM内存模型是指Java虚拟机管理程序运行时内存的方式,包括内存划分、内存分配和对象回收等机制。 JVM模型的组成部分包括类加载器、解释器、即时编译器、垃圾收集器等。类加载器负责将Java类加载到JVM中,并将其转换为可执行代码;解释器负责解释字节码并执行相应的指令;即时编译器则将频繁执行的代码编译成本地机器码,以提高程序的执行效率;垃圾收集器则负责回收程序运行时不再使用的内存。 JVM内存模型规定了Java程序运行时内存的分配和管理方式。JVM内存模型将内存划分为不同的区域,包括方法区、堆、虚拟机栈、本地方法栈和程序计数器。其中,堆是Java程序运行时内存中最大的区域,用于存储对象实例。虚拟机栈和本地方法栈则用于存储程序执行时的局部变量和方法调用信息。方法区用于存储已加载的类信息、常量池、静态变量等数据。程序计数器则用于记录当前线程所执行的字节码指令位置。 JVM内存模型还包括垃圾回收机制,用于自动回收程序运行时不再使用的内存。垃圾回收机制采用标记-清除、复制、标记-整理等不同的算法来回收内存。 总之,JVM模型和JVM内存模型是Java程序运行时的重要组成部分,了解和掌握它们的工作原理对于编写高效、稳定的Java程序至关重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值