JVM学习笔记-内存分配-堆内存模型

一、堆内存结构

对内存的结构如下图:
file

  1. 新生代用来放新分配的对象;新生代经过垃圾回收,没有回收掉的对象,被复制到老年代
  2. 老年代存储对象比新生代存储对象的年龄要大的多
  3. 老年代存储一些大对象
  4. 整个堆大小= 新生代 + 老年代
  5. 新生代 = Eden + 存活去
  6. 在JDK8之前,有持久代,用来存放Class,Method等元信息的区域,JDK8后,取而代之的是元空间(MetaSpace),元空间并不在虚拟机里面,而是直接使用本地内存。

二、对象的内存布局

宏观如图:
file
对象在内存中存储的布局(每种虚拟机实现不一,以HotSpot为例)分别为:对象头、实例数据、对其填充

  1. 对象头包含两部分:
    (1)存储对象自身的运行数据:HashCode、GC分代年龄、锁状态标志等
    (2)类型指针:对象指向它的类的元数据的指针
    file
  2. 实例数据:真正存放对象实例数据的地方
  3. 对齐填充:这部分不一定存在,也没有什么特别的含义,仅仅是占位符。 在HotSpot要求对象起始地址都是以8字节的整数倍,如果不是,就占位对齐

三、对象的访问定位

在JVM规范中只规定了reference类型是一个指向对象的引用,但没有规定这个引用具体规定如何去定位,如何访问堆中对象的具体位置,因此对象的访问方式取决于JVM的实现,目前主流的有:使用句柄 或者使用指针,这两种方式

使用句柄(好处:对象实例和对象类型指针修改对reference无影响|缺点:速度略慢)

Java对中会划分出一块内存来作为句柄池,reference中存储句柄的地址,句柄中存储对象的实例数据和类元数据的地址,如下图:
file

使用指针(好处缺点与使用句柄相反)

使用指针:Java堆中会存放访问类元数据的地址,reference存储的就是对象的地址,如下图:
file

版权声明:
作者:十下
链接:http://blog.edkso.cn/?p=948
来源:十下博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>