Java中对象的访问

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

1、对象的创建


补充:

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



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


  • 对象创建的线程安全性:当使用指针碰撞进行对象内存分配的时候,如果给对象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类型的引用类型的变量存储的是对象的地址
  • 优点:快速高效,减少中间一次句柄地址指针定位开销



猜你喜欢

转载自blog.csdn.net/xiaoqiu_cr/article/details/79972521