zoukankan      html  css  js  c++  java
  • 浅析JVM对象的创建过程、内存布局以及访问定位

    一、对象的创建过程

      关于对象的创建,第一反应是 new 关键字。Student stu =new Student("**","18");就拿这句代码来说:

    1、虚拟机首先会去检查Student这个类有没有被加载,如果没有,首先去加载这个类到方法区。

    2、然后根据加载的Class类对象创建stu实例对象。

    3、需要注意的是,stu对象所需的内存大小在 Student类加载完成后便可完全确定。

    4、内存分配完成后,虚拟机需要将分配到的内存空间的实例数据部分初始化为零值,这也就是为什么我们在编写Java代码时创建一个变量不需要初始化。

    5、紧接着,虚拟机会对对象的对象头进行必要的设置,如这个对象属于哪个类,如何找到类的元数据(Class对象)、对象的锁信息、GC分代年龄等。

    6、设置完对象头信息后,调用类的构造函数。

      其实讲实话,虚拟机创建对象的过程远不止这么简单,我这里只是把大致的脉络讲解了一下,方便大家理解。

    二、对象的内存布局

      刚刚提到的实例数据,对象头,有些小伙伴也许有点陌生,这一小节就详细讲解一下对象的内存布局。

      对象创建完成后大致可以分为以下几个部分:

    1、对象头:对象头中包含了对象运行时一些必要的信息,如GC分代信息,锁信息,哈希码,指向Class类元信息的指针等。

      其中对开发者比较有用的是锁信息与指向Class对象的指针

      关于指向Class对象的指针其实很好理解。比如上面那个Student的例子,当我们拿到stu对象时,调用Class stuClass=stu.getClass(); 的时候,其实就是根据这个指针去拿到了stu对象所属的Student类在方法区存放的Class类对象。

    2、实例数据:实例数据部分是对象真正存储的有效信息,就是程序代码中所定义的各种类型的字段内容。

    3、对齐填充:虚拟机规范要求对象大小必须是8字节的整数倍。

      对齐填充其实就是来补全对象大小的。

    三、对象的访问定位

      谈到对象的访问,还拿上面学生的例子来说,当我们拿到stu对象时,直接调用stu.getName();时,其实就完成了对对象的访问。

      但这里要说一下的是,stu虽然通常被认为是一个对象,其实准确来说是不准确的,stu只是一个变量,变量里存储的是指向对象的指针,(如果干过C或者C++的小伙伴应该比较清楚指针这个概念),当我们调用stu.getName()时,虚拟机会根据指针找到堆里面的对象然后拿到实例数据name。

      需要注意的是,当我们调用stu.getClass()时,虚拟机会首先根据stu指针定位到堆里面的对象,然后根据对象头里面存储的指向Class类元信息的指针再次到方法区拿到Class对象,进行了两次指针寻找。具体讲解图如下:

  • 相关阅读:
    ThinkPhp框架分页查询和部分框架知识
    tp框架增删改
    WAMP中mysql服务突然无法启动 解决方法
    thinkphp框架 的 链接数据库和操作数据
    php 全局使用laravel的dd和dump
    给centos装图形界面 widowsx
    marquee标签的使用
    微信公众号开发入门教程
    laravel admin引入css js报错 https
    利用Croppie裁剪图片并后台保存
  • 原文地址:https://www.cnblogs.com/goloving/p/15268592.html
Copyright © 2011-2022 走看看