java底层(四)HotSpot如何表示java对象

我们通常知道
在应用程序的开发中类像是生产线上的模板 按照模板创建出相应类的对象
然后机器按照预定义的指令向不同对象发送消息

对象的表示机制

对象在jvm内部是如何表现的 内存中如何存储

JVM内部对象的表示系统
面向对象的几个主要特征 封装 继承 多态
HotSpot基于C++实现
假想在HotSpot内为每个java类生成一个C++类 在内部创建域和方法与C++相同的等体

OOP_Klass二分模型 普通对象指针 用来描述对象实例信息 Klass 用来描述java类
OOP对象 主要用于表示对象的实例数据 没必要有虚函数
Klass 对象含有vtbl 父类klass_vtbl 根据java对象的实例类型进行C++分发
OOP就可以找到所有的虚函数 避免了每一个对象分配一个vtbl指针

Klass实现语言层面的java类 Klass基类实现
实现java对象的分发功能 Klass子类提供虚函数实现

OOPs模块 分为OOP框架和Klass框架

在程序的运行过程每创建一个java对象 jvm 创建一个oop表示java对象
公共基类oopDesc 在oop.hpp中定义
class oopDesc {
friend class VMStructs;
private:
volatile markOop _mark;
union _metadata {
wideKlassOop _klass;
narrowOop _compressed_klass;
} _metadata;
根据jvm使用的业务对象类别有不同的子类
比如 instanceoopdesc 类的实例 而 arrayoopdesc表示数组

oop框架的类型层次结构

在虚拟机内部通过一个instanceoopsdesc表示一个java对象

对象在内存中的布局分成连续的两部分
instanceoopdesc 可以被称为对象头
和实例数据

对象头包含两部分信息内容 Markwork _mark成员 存储对象运行时的记录信息 比如hashcode gc年龄 锁状态标志 线程持有的锁 偏向线程id 偏向时间戳 数据类型为 markoop 占用内存的大小与虚拟机位长一致
元数据指针 _metadata 指向描述类型klass对象的指针 klass 对象包含了实例对象所属类型的元数据 使用该指针定位到方法区内的类型信息

length
instanceOopdesc和arrayOopsdesc 区别在于arrayoop增加了一个描述数组长度的字段

OOPS对象在HotSpot内部会被大量创建和频繁使用

Hotspot的设计者 在oops设计时尽量的性能和内存优化 比如内联
oops类中绝大多数方法成员被定义为内联方法 并且短小代码实现 降级调用开销

关于对象头的布局
每创建一个java对象 jvm内部维护一个对象头
对象内存空间占用率 实例数据和对象头和实例数据空间
如何在有限空间存储丰富的信息

其中有对类元数据指针压缩存储

usecompressedoops 作用是在64位jvm机器上 对类元数据指针32压缩
指针压缩配置选项
当未使用压缩时 使用wideklassoop类型 等价于klassoopdes指针
当压缩时使用 narrowOop类型 相当于32位无符号整型变量

与oop相关的vm选项

markwork的设计类似于网络协议报文头 划分为多个比特位区间 并在不同对象状态下赋予不同意义

HotSpot的对象5种状态 枚举状态

元数据指针 用来指向对象所属类型的元数据
OOPS类型层次
typedef class oopDesc* oop;
typedef class instanceOopDesc* instanceOop;
typedef class methodOopDesc* methodOop;
typedef class constMethodOopDesc* constMethodOop;
typedef class methodDataOopDesc* methodDataOop;
typedef class arrayOopDesc* arrayOop;
typedef class objArrayOopDesc* objArrayOop;
typedef class typeArrayOopDesc* typeArrayOop;
typedef class constantPoolOopDesc* constantPoolOop;
typedef class constantPoolCacheOopDesc* constantPoolCacheOop;
typedef class klassOopDesc* klassOop;
typedef class markOopDesc* markOop;
typedef class compiledICHolderOopDesc* compiledICHolderOop;

Hotspot对象访问的机制

对象引用存对象指针 对象存类instanceKlass的指针

当java程序在jvm中运行时 由new创建的java对象 将会在堆中分配对象实例。
对象实例包含实例数据外 还有对象头。

java程序通过对像实例的引用 访问到jvm表示的对象instanceoop。
当需要访问该类时,如果程序要调用对象的方法或者访问类变量 instanceoop持有的类元数据指针_metadata定位到位于该方法的 instanceKlass对象

jvm内存对象访问机制 HotSpot指针方式 还有另外一种访问句柄方式

Klass基础结构 层次结构 instanceKlass

JVM如何规定实例数据的存储顺序

Klass的类层次结构

核心结构
klass 定义了共享的结构和行为 描述了自身布局和其他类的关系
Klass对象的内存布局图

klass的属性成员
_layout_helper 值表示instance大小
_name instance类型
_java_minrror java层镜像类 (java7它含有静态成员) 是Class类型的实例
一部分表示父子关系 链表

……
_next_sibling
….
_biased_lock_revocation_count

运行时表示表示java内部类型的机制

hotSpot解决方案 为每一个加载的java类创建instanceKlass对象 用在jvm层表示java类
它的成员变量在类解析时完成赋值
_methods _method_ordering _local_inferfaces _transitive_interfaces _fileds _constants _class_loader +protection_domain
它的末尾字段 可变长度 java vtables javaitables 静态变量 非静态变量oop_map块

vtable_len 以字长为单位 oop_map 便宜量长度 对域的索引

instanceKlass内存布局

实例数据的存储顺序
字段存储顺序 和虚拟机分配策略 -XX:FiledAllocationStyle

HotSpot的默认分配策略 CompactFileds true含义吗 太麻烦了不讲

关于更具体的学习—————
HSDB的使用 太吵淡了 不讲

最后总结下
虚拟机将是将对象和类型分开表示,oop描述对象, klass描述类型
对象在内存中的布局分为对象头和实例数据
对象头还包含对应类型的klass指针 可以通过对象头访问类型信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值