• JVM——java虚拟机创建对象与寻址对象


    JAVA虚拟机创建对象的流程

     

    JAVA对象的结构

    空间分配

    空间分配的两种方式

    指针碰撞

        当已分配空间被集中存放,已分配和未分配空间使用一个指针来标记时,分配新的空间只需要移动该空间即可,此方法为指针碰撞。适用于GC算法会做COMPACT的情况。

    空闲列表

        当已分配的空间是分散存放时,虚拟机必须维护一个记录了哪些内存块是可用的列表,此为空闲列表,需要分配新空间时只需要从该列表中获取。

    解决空间分配线程安全问题的两种方式

    CAS方式失败重试

        顾名思义,遇上分配时的线程冲突时,会再次进行空间分配直至成功。实现简单直观但是效率较低

    空间划分

        为每个线程分配单独的一块空间,该空间只用来给该线程做创建对象分配空间时使用,这单独的空间被称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。当该线程的TLAB分配光了后,才需要同步锁定,效率较高。是否使用TLAB可以通过虚拟机参数指定。

    设置对象头(对象管理的必要信息)

      空间初始化成0后(初始化不包含对象头),需要针对对象设置一些必要信息,如:对象归属于哪个类、对象的hash码、对象的GC分代年龄等,这些信息都放在对象头中。根据虚拟机状态——如是否使用偏向锁,设置对象头。

    对象头包含信息

        对象头包含两部分信息:

        • 运行时数据(hash码、GC分代年两、持有锁、锁标识状态、偏向线程ID),这部分数据被称为Mark Word。
        • 类型指针,用来说明该对象是哪个类的实例。

    设置对象实例数据

      对象的实例数据主要是根据JAVA代码的编写生成的,包含包括父类在内的各种类型的字段,其字段安排的顺序受虚拟机实现及代码的编写影响。

    虚拟机安排字段的方式

        1、相同宽度的字段放在一起

        2、父类的字段放在子类的前面

        3、窄小的变量也会被安排在父类的字段空隙中(C++的内存安排规则,HotSpot VM是由C++语言编写)

    填充字段

      HotSpot VM要求对象的其实位置必须是8字节的整数倍,也就是说对象必须是8字节的整数倍,所以需要填充占位(这也是一句C++的规则来的)。

    对象的定位

      JAVA程序访问对象需要通过栈上的reference数据操作堆上的具体对象。reference对象要么通过指向句柄再指向对象实例,要么直接指向对象实例。

    以句柄的方式访问

        使用句柄方式访问对象实例,需要在堆中划分出一块儿句柄池,句柄与指针类似,记录了具体的实例所存放的地址。这种方式的好处是reference是稳定的,当对象实例地址改变时,只需改变句柄中的对象实例指针。

    以指针直接访问

        以指针方式访问对象实例,是通过reference直接指向对象实例,优点是速度快,因为比句柄访问方式少了一次寻址的过程。

    PS:对象实例数据指的是具体的对象,对象类型对象指的是该实例数据对象所属的Class类对象。

  • 相关阅读:
    类的访问级别
    包和静态引入
    数组
    流程控制
    适合初学者的ROS机器人教程(3): ROS下使用Python对UR5机器人建模与控制
    适合初学者的强化学习教程(1): python使用gym实践和注意事项
    适合初学者的ROS机器人教程(1): Ubuntu下ROS创建自己的包和使用github下载的包
    适合初学者的ROS机器人教程(2): Ubuntu下ROS使用Gazebo和Rviz对UR5机器人建模
    spyder使用IPython的ipdb调试
    mysql创建外键
  • 原文地址:https://www.cnblogs.com/qq455988971/p/8304256.html
Copyright © 2020-2023  润新知