读书笔记《深入理解java虚拟机》-- Java对象于HotSpot探秘

Java对象于HotSpot探秘

导论

这篇文章是从内存上大致总结在HotSpot中JAVA对象的部分实现的细节。
首先我们先从java对象的创建出发,了解java对象的内存分配的方式和内部布局的细节。之后为了引出jvm的重点之一垃圾回收(本篇文章先不涉及),我们需要再了解java虚拟机内部是怎么找到到Java对象的。
这个就是本篇文章的阅读思路。

一、JAVA对象的创建于内存的变化

  • JAVA对象内存划分的两种方式

    1. 指针碰撞

    假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的治时期,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称之为“指针碰撞”(Bump The Pointer)

    适用
    这种简单的高效的方式适用于带有空间压缩整理的能力的垃圾收集器。例如:Serial、ParNew等收集器。
    图解
    读书笔记《深入理解java虚拟机》-- Java对象于HotSpot探秘_第1张图片

    2. 空闲列表

    虚拟机通过维护一张内存列表,表上记录的是那些内存块可以使用,再分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种方式称之为“空闲列表”(Free List)

    适用
    这种较为复杂的空闲列表方式被适用于基于清除算法的收集器。例如:CMS收集器。
    图解
    读书笔记《深入理解java虚拟机》-- Java对象于HotSpot探秘_第2张图片

  • JAVA内存分配的并发问题

对象创建再虚拟机中是非常频繁的行为,即使仅仅修改一个指针所指向的位置,在并发的情况也不是线程安全的,可能出现正在给对象A分配内存,指针还没有来得及修改,对象B又同时使用了原来的指针来分配的内存的情况

  • 解决方式

    1. 对分配空间的操作进行同步处理。
    2. 预先给不同线程提前分配一小部分的内存作为缓冲。

二、对象创建和内存布局

  • 对象创建

    对象经过上面的操作之后,已经分配到了内存空间。但是此时的对象还不具备可以访问的能力,此时需要赋值操作才可以访问。

    内存初始值

      内存的初始值大致分为两块:对象元数据放置对象头中(对象头在下面的对象布局中)和非对象头的内存空间初始化为0
      经过这两步骤,对于虚拟机来说对象就已经创建完毕了,但是对于业务代码来说class文件里面的 初始化操作还没有执行。

    对象初始值

      这一步就是关构造器、class等默认初始值赋值创建。经过这一步之后才会出现一个符合程序员设置的java对象。

  • 对象布局

    对象内部划分

    在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

    对象头

    对象头包括两类信息:“Mark Word”类型指针

    Mark Word

    “Mark Word” 是用于存储对象自身的运行时数据,如哈希码,GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别位32个比特和64个比特。

    类型指针

    类型指针,是对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身

三、对象的访问定位

《Java虚拟机规范》规定java程序会通过栈上的reference数据来操作对上的具体对象,至于操作的方式则需要Java虚拟机本身进行提供。

  • 对象访问的两种方式

    • 使用句柄

      Java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,这个句柄包含了对象实例数据与类型数据各自具体的地址信息

      优缺点
       使用句柄来访问因为有一个指针重新指向,这个会导致java对象的访问速度变慢。但是在Java对象移动的时候非常方便,只需要改句柄池的对象指针即可。
      图解读书笔记《深入理解java虚拟机》-- Java对象于HotSpot探秘_第3张图片

    • 直接指针

      Java对象的地址直接存储在reference中。

      优缺点
       优缺点于句柄正好相反。
      图解
      读书笔记《深入理解java虚拟机》-- Java对象于HotSpot探秘_第4张图片

    总结

    由于JAVA程序对对象的访问过于频繁,因此对于HopSpot而言,主要使用的是第二种方式(直接访问)进行对象的访问。

你可能感兴趣的:(JAVA学习,jvm,指针,java)