jvm对象创建和内存分配机制

对象创建的过程

在这里插入图片描述

类加载检查

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
new指令对应到语言层面上讲是,new关键词、对象克隆、对象序列化等。

分配内存

  1. 如何划分内存?
  2. 并发情况下,可能出现a线程正在给对象A分配内存,指针还没来得及修改,线程b又同时使用原来的指针给对象B分配内存。
分配内存的方法
  1. 指针碰撞 (默认使用)
    如果java堆中内存是绝对规整的,所有用过的内存放一边,没有用过的内存放另一边,中间放着一个指针作为分界点的指示器,那所分配的内存仅仅就是把指针挪动一段与对象大小相等的距离。
  2. 空闲列表
    如果java堆中内存不是规整的,那么就没办法使用指针碰撞了,虚拟机会维护一个空闲列表,记录哪块区域是可以使用的,在分配内存的时候从列表里面找出一块足够大的空间划分给对象实例,并更新列表上的记录。
对象内存分配的流程

在这里插入图片描述

栈内分配

为了减少临时对象在堆内的分配数量,JVM通过逃逸分析确定该对象不会被外部方法访问,这样就可以将对象在栈上分配内存。这样对象所占的内存就会随着栈帧出栈而结束,减轻了垃圾回收的压力。

对象逃逸分析

就是分析对象动态作用域,当一个对象在方法中被定义后,它可能被外部所引用,例如作为调用参数传递到其他地方中。
结论:栈上分配依赖于逃逸分析和标量替换

标量替换

通过逃逸分析确定该对象不会被外部访问,并且对象可以被进一步分解时,JVM不会创建该对象,而是将该对象成员变量分解若干个被这个方法使用的成员变量所代替,这些代替的成员变量在栈帧或寄存器上分配空间,这样就不会因为没有一大块连续空间导致对象内存不够分配。开启标量替换参数(-XX:+EliminateAllocations),JDK7之后默认开启。

分配内存并发问题的解决
  1. CAS(compare and swap)
    CAS 是乐观锁的一种实现方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。
  2. 本地线程分配缓存 (Thread Local Allocation Buffer , TLAB)
    把内存分配的动作按照线程划分在不同的空间进行,即每个线程在java堆中预先分配一小块内存。通过
    -XX:+UseTLAB参数打开TLAB (默认打开), -XX:TLABSize 指定大小。当对象大于 TLAB 中的剩余内存或 TLAB 的内存已用尽时,再采用上述的 CAS 进行内存分配。

初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

设置对象头

初始化零值之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头Object Header之中。
在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、 实例数据(Instance Data)和对齐填充(Padding)。

对象头分为两个部分
  1. Mark Word 标记字段(32位占4个字节, 64位占8字节)
    主要用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时 间戳等。
  2. Klass Pointer 类型指针 (开启压缩占4字节,关闭压缩占8字节)
    即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
对齐填充

保证对象是8个字节的整倍数

什么是指针压缩?
  1. 在jdk1.6开始支持指针压缩。在开启指针压缩情况下,对象头的类型指针占4个字节,未开启的情况下占8个字节。
  2. 启用指针压缩:-XX:+UseCompressedOops(默认开启),禁止指针压缩:-XX:-UseCompressedOops
为什么要进行指针压缩?
  1. 使用较大指针在主内存和缓存之间移动数据,占用较大宽带,同时GC也会承受较大压力.
  2. 堆内存小于4G时,不需要启用指针压缩.
  3. 堆内存大于32G时,压缩指针会失效.

执行 方法

执行代码属性赋值和执行构造方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值