画图学 JVM(十一)10 Java 对象的实例化、内存布局与访问定位

一、结构内容

在这里插入图片描述

二、Java 对象实例化过程

1. 大厂面试问题

  1. Java 对象在 JVM 中如何存储?
  2. Java 对象头中保存哪些内容?

2. Java 对象创建的方式(5 种)

  1. new:及其各种变种,包括单例模式构建模式中调用静态方法(其实间接调用了私有构造方法),这是最常见的方式。
  2. 反射:
  • Class 类 newInstance 方法, 要求空参构造函数、public。 JDK 9 中已标记为过时方法。
  • Constructor 类的 newInstance 方法,可以调用带参构造器。也不要求 public。
  1. clone:用于实现了 Clonable 的类,不调用任何构造器
  2. 反序列化:使用来自文件或网络的字节信息重新构建类
  3. 第三方框架:如 Objenesis 等

3. Java 对象的创建过程(6 步骤)

在这里插入图片描述

  1. 类型信息加载
    虚拟机遇到 new 指令,会去 MetaSpace 常量池中定位类符号引用。如果没有找到会通过类加载机制对类型进行加载,并生成相应的 Class 对象。
  2. 为对象分配内存
    因为采用的 GC 机制(压缩整理功能)不同,会导致堆内存规整情况不同。因此有两种内存分配机制:
  • 指针碰撞(Bump the Pointer),用于内存规整的情况。内存分为已使用区和空闲区,用一个指针指示两个分区的分界。给对象分配内存时,只需将指针向空闲区移动对象大小即可。
    在这里插入图片描述

  • 空闲列表(Free List)
    已使用和空闲内存相互交错,虚拟机维护了一个列表,记录了哪些内存块时可用的,在分配的时候从列表中找出一块足够大的空间划分给对象实例。并更新列表内容。
    在这里插入图片描述

  1. 处理并发安全问题
    采用 CAS 机制尝试分配,同时也采用 TLAB 预先为线程分配小块堆空间
  2. 设置实例字段默认值
    所有实例字段分配默认值,保证在没有赋值时可以直接使用
  3. 设置对象的对象头信息
    对象头中会存放对象运行时元数据和类型指针。详见下一节。
  4. 执行 init 方法进行初始化
    显式初始化成员变量,执行代码块和执行构造方法。此时才按程序员的意愿进行初始化。至此,一个对象才完整的创建出来。

三、Java 对象的内存布局

1. 一个示例

	public class CustomerTest{
	
	    public static void main(String[] args) {
	        Customer customer = new Customer();
	    }
	}
	
	class Customer {
	    int id = 1001;
	    String name;
	    Account account;
	    {
	        name="匿名客户";
	    }
	
	    public Customer() {
	        account = new Account();
	    }
	}
	
	class Account {
	}

在这里插入图片描述

说明

  1. 主线程的虚拟机栈中有一个 main 方法对应的栈帧, 栈帧中的局部变量表有一个 customer 引用类型指向 堆中的 Customer 对象
  2. Customer 对象中内存划分三个区域:对象头、实例数据和对齐填充
  3. 对象头中的类型指针指向方法区中 Customer 类元信息

2. 对象内存划分详细说明

2.1 对象头

2.2 实例数据

在这里插入图片描述

2.3 对齐填充

非必须,仅仅起到占位符的作用,类比于快递盒中的泡沫,用于让堆内存更规整。

四、Java 对象的访问

Java 对象是通过虚拟机栈上的引用变量来实现访问的。

1. 句柄访问

在这里插入图片描述堆区划分成句柄池和实例池,栈上引用指向句柄池中的句柄。每个句柄中包括:

  • 指向对象实例数据的指针:指向对象池中的对象
  • 执行对象类型数据的指针:指向方法区中的对象类型

优点

在垃圾回收等过程中对象发生移动时,只需要更改句柄而不需要堆栈上的引用进行修改,比较稳定。

2. 直接指针

在这里插入图片描述栈上的引用变量直接执行堆中的对象实例,对象实例中包含了一个指向对象类型数据的指针。

优点

  1. 无需额外保存句柄信息,节省内存空间
  2. 比句柄方式少了一次访问操作,因此会更高效

附件

看图学 JVM 目录

本文没有 PPT

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值