zoukankan      html  css  js  c++  java
  • (二)jvm-Java对象的创建、访问

    以Hotspot虚拟机为例,描述对象的 创建过程。

    对象的创建

    通过new关键字创建对象

    1. 虚拟机在遇到new关键字后先去常量池中寻找一个类的符号引用,
    2. 检查这个类是否被加载,解析和初始化,如果没有则执行类加载过程
    3. 为对象分配内存
      在类加载过程完成后类就已经确定了对象所需要的大小,然后从堆中划分出确定大小的一块内存
    4. 虚拟机初始化对象零值
      内存分配完成后,会对分配的内存空间进行零值初始化,保证java对象实例字段在java代码中可以不赋初始值就直接使用,程序可以访问到这些零值。
    5. 设置对象头信息
      例如对象是哪个类的实例,如何找到类类信息,hash码,GC分代年龄等。
    6. java程序初始化对象
      经历完上面过程,虚拟机层面看一个对象已经创建完成,但java程序层面的对象创建才刚刚开始。虚拟机执行完new指令后会接着执行方法,这时候对象才会按照程序员的意图进行初始化,这样产生的对象才算是真正可用的对象。

    对象内存布局

    对象的内存布局分为三个区域
    对象内存布局

    • 对象头
      存储对象自身的运行时数据:比如HashCode,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等
      存储类型指针:对象指向它的类元数据的类型指针,虚拟机通过这个指针来确定这个对象是哪个类的实例(这不是必须的)。
    • 实例数据
      实例数据是对象真正存储的有效信息,也就是在程序代码中定义的各种类型的字段内容。
    • 对其填充
      不是必然存在的,没有特别的含义,仅起着占位符的作用。

    对象的访问定位

    java程序通过栈(Heap)上reference(引用)数据来操作堆上的具体对象。
    目前访问对象的两种方式为句柄和直接指针两种

    • 通过句柄访问
      java堆会划出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄地址中包含了对象实例数据与类型数据各自的具体地址信息。如下图:
      句柄访问

    • 直接指针访问
      reference中直接存储对象地址,如下图:
      直接指针访问

    • 两种访问方式的对比
      句柄访问:存储的是稳定的句柄地址,对象改变时仅改变句柄的实例数据指针,而reference本身不需要修改
      直接指针:最大的好处是访问速度更快,节约了一次指针定位时间的开销(Hotspot使用这种方式)

    关注微信公众号一起读书学习交流
    CodeBooker

  • 相关阅读:
    求助求助——请教各位高手,抽出一点宝贵的时间根据这个实例讲解一下应该如何分层呢?
    我的数据访问函数库的源代码(一)—— 共用部分
    我的网站的结构说明
    我的网站的后台管理的结构图。
    [转载]大项目中项目经理的作用
    ASP.net实现无扩展名的URL重写。简单、方便、无需ISAPI。
    我的数据访问函数库的源代码(三)——返回结构数组
    数据访问层的使用方法
    我的数据访问函数库的源代码(二)—— SQL语句部分
    [导入]用户登录及验证用户是否登录的代码
  • 原文地址:https://www.cnblogs.com/vincili/p/9310700.html
Copyright © 2011-2022 走看看