在运行时数据区我们了解以后,知道了我们将对应的信息放置到我们逻辑分区的内存中后,接下来就是这些数据是如实创建对象,及其对象的布局,和访问

对象的创建

1.首先在java中,对象似乎通过new关键字创建的,也就是说通过这个创建指令来创建对象,下面简单画一下执行过程
HotSpot虚拟机对象了解 (java内存区域 二)
2. 当类加载完成检查后,需要为对象创建的内存大小区间已经完全确认,为对象分配内存实质上是将大小确定的内存空间从java堆中划分出来。
HotSpot虚拟机对象了解 (java内存区域 二)
从java堆分配内存,可能内存是绝对完整的,也可能存在内存不是完整的一整块内存,即已使用内存和未使用内存交错。

  • 针对内存绝对完整内存,可以使用指针碰撞方式。为新对象分配内存,只需要移动一段空间大小与需要分配内存大小相等的空间对应的指针处即可。
    HotSpot虚拟机对象了解 (java内存区域 二)
  • 针对内存不是完整的,可以使用空闲列表方式。当需啊为新对象分配一块较大的内存,需要更新空闲列表状态。如下图所示
    HotSpot虚拟机对象了解 (java内存区域 二)
    关于java堆是否完整,与采用的垃圾回收器是否带有压缩功能有关。例,使用Serial、ParNew等带有压缩功能的收集器系统采用的分配算法是指针碰撞,而使用CMS这种基于标记-清除算法的收集器,采用空闲列表。
  1. 除了考虑如何分配内存空间之外,还需要考虑并发情况下,如指针碰撞修改指针位置时候,并发会造成不安全。解决这个问题有两个方案
  • 对内存空间分配进行同步控制,实际上虚拟机采用CAS(compare and swap)+失败重试保证原子性
  • 使用本地线程缓存技术、也就是TLAB(Thread Local Allocation Buffer),也就是每一个线程拥有独立的空间分配内存,可以理解为拥有了内存的隔离性。可以通过设置参数:-XX:+/-UseTLAB来控制虚拟机是否使用TLAB
  1. 内存分配完成后,虚拟机将分配的内存空间都初始化为零,但是不包括对象头。接下来,虚拟机将对对象进行必要的设置,例如这个对象是哪个类的实例、如何找到类的元数据信息、对象哈希码、对象的GC分代年龄等信息。这些信息存储在对象头中。
  2. 当上述工作都完成后,虚拟机创建对象步骤已经完成,所有的字段都已经初始化为零。紧接着执行new指令后的<init>方法,也就是程序中的构造函数,按照程序员的意图对程序进行赋值,这样一个真正的对象创建完成。

对象的内存布局

  1. 在hotsopt虚拟机中,对象的内存存储划分为三块区域:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)

TODO

对象的访问定位

TODO

相关文章:

  • 2021-10-29
  • 2021-05-29
  • 2021-08-31
  • 2021-05-29
  • 2021-09-22
  • 2021-09-04
  • 2021-12-13
  • 2021-06-14
猜你喜欢
  • 2021-07-05
  • 2021-09-13
  • 2021-03-31
  • 2021-04-02
  • 2021-10-31
  • 2021-10-20
相关资源
相似解决方案