Java中对象的访问

1、举例:实例化一个对象

1、对象的创建

Java堆创建对象时分配内存空间的方法:

  • 指针碰撞指针向空闲空间移动和对象内存大小相等的距离

  • 空闲列表:从空闲列表里面选择一个足够大的空间分配给对象

对象创建的线程安全性:当使用指针碰撞进行对象内存分配的时候,如果给对象A分配了内存,指针还没来得及修改,又为对象B分配了内存。

方案一:对分配内存空间操作进行同步处理:采用CAS配上失败重试的方式保证更新操作的原子性(缺点是时延太高)

方案二:为每个线程在Java堆中预先分配一个本地线程分配缓冲区TLAB,使得不同的线程分配在不同的空间执行。哪个线程需要分配,就在对应的TLAB执行。

2、对象的内存布局

补充:

  • 运行时数据:32bit/64bit,俗称“mark word”,用于存储哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等
  • 类型指针:对象指向类元数据的指针,用于确定对象属于哪个类的实例
  • 数组长度:针对对象为数组类型
  • 实例数据:存储顺序根据虚拟机分配策略参数和字段在Java源码中的定义顺序。父类定义的变量出现在子类之前。如果compactFields为true,那么子类的较窄的变量可以插在父类的缝隙中。
  • 对齐填充:对象的大小为8字节的整数倍

3、Java虚拟机栈访问Java堆中的对象

  • 句柄访问:从Java堆分出一部分内存区域作为句柄池,一部分作为实例池。用于存放对象实例数据指针对象类型数据指针。Java虚拟机栈中的reference类型的本地变量存储的是句柄的地址
  • 优点:对象移动只会改变对象实例数据的指针不会改变Java虚拟机栈中的reference类型变量的值

  • 直接指针访问:Java虚拟机栈中的reference类型的引用类型的变量存储的是对象的地址
  • 优点:快速高效,减少中间一次句柄地址指针定位开销

欢迎关注我的公众号:小秋的博客 CSDN博客:https://blog.csdn.net/xiaoqiu_cr github:https://github.com/crr121 联系邮箱:rongchen633@gmail.com 有什么问题可以给我留言噢~
原文地址:https://www.cnblogs.com/flyingcr/p/10326898.html