JVM总结

JVM总结

运行时数据区

Java虚拟机运行时数据区
线程共享:

  • 方法区(Method Area):用于存放已被虚拟机加载的类型信息、常量、静态常量、即时编译器编译后的代码缓存等数据。
    • 运行时常量池(Runtime Constant Pool):是方法区的一部分,用于存放Class文件中的常量池表,常量池表用于存放编译器生成的各种字面量与符号引用,这部分类容将在类加载后存放到方法区的运行时常量池中。
  • (Java Heap):Java堆在虚拟机启动时创建,用来存放Java对象实例。

线程私有:

  • 虚拟机栈(Java Virtual Machine Stack):Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会创建一个栈帧用于存放局部变量表、操作数栈、动态连接、方法出口等信息。每个方法从调用到执行完毕的过程,对应于栈帧在虚拟机栈中从入栈到出栈的过程。
  • 程序计数器(Program Counter Register):当前线程所执行的字节码行号指示器,用于指示程序执行到哪一行。
  • 本地方法栈(Native Method Stacks):与虚拟机栈类似,不同的是,虚拟机栈为Java字节码服务,而本地方法栈为Native方法服务。

对象的创建

new 一个对象在JVM中发生了什么?

  1. 首先看在运行时产量池中是否能找到这个类的符号引用,并且检查这个类是否被加载、解析和初始化过。如果没有,则先执行类加载过程。

  2. 为新生对象分配内存。对象所需内存的大小在类加载过程就已经确定。然后在堆中为该新对象分配一块内存区域。分配的方式有指针碰撞(Bump the Pointer)和根据空闲列表分配。如果堆是规整的,则直接挪动指示未分配和已分配区域分界点的指针,这种方式成为指针碰撞。如果不是规整的,即已分配和未分配交叉混合在一起,则根据空闲列表进行分配。

    • 在如何划分可用空间中,仅仅修改指针的指向并不是线程安全的。JVM使用两种方式来保证线程安全。一种是堆分配内存空间的动作进行同步——采用CAS配上失败重试的方式保证更新操作的原子性,另一种是吧内存分配的动作按照线程划分在不同的空间之中,即每个线程在Java堆中于线分配一小块内存,成为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB)
  3. 将分配到的内存空间(不包括对象头)初始化为0

  4. 对对象进行必要的设置,比如说设置对象头,或者说按照构造函数进行初始化。

对象的内存布局

对象在堆内存中的存储布局分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

  • 对象头:包含Mark Word和类型指针。Mark Word用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,在32位和64位虚拟机中分别为32bit/64bit。类型指针是对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例。

  • 实例数据:对象的信息,即定义的各种类型的字段内容。

  • 对齐填充:占位符。由于HotSpot中规定的对象的大小为8字节的整数倍,如果对象头和实例数据不到8的整数倍字节,则通过对齐填充来补全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值