您的位置:首页 > 编程语言 > Java开发

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

2018-01-14 14:31 459 查看
我们通常知道

在应用程序的开发中类像是生产线上的模板 按照模板创建出相应类的对象

然后机器按照预定义的指令向不同对象发送消息

对象的表示机制

对象在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;

ae94

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指针 可以通过对象头访问类型信息
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: