(gdb) p obj $15 = (oopDesc *) 0xf3885d08 (gdb) p * obj $16 = { _mark = 0x70dea4e01, _metadata = { _klass = 0x2000070e, _compressed_klass = 536872718 }, static _bs = 0x7f658801eea8 }
1.介绍oo对象
现在先看最长使用的oop对象的定义,jvm的二分模型就是oop和class,所有的对象在hotspot层全被具体化成了oop对象,
oop的结构很简单,表示一个hotspot对象,也可以理解为一个java对象(不过包了一层handle才是java对象), 比如在java中创建一个对象
Student xm=new Student();
xm.name="小明";
xm.age=18;
这个xm就是oop,,这个oop被放在堆中,代表的就是xm这个对象,那么这个对象有成员变量name,age,那么oop对象在内存中的
oop对象 | |
内存地址64位 | _mark属性 |
内存地址32(压缩指针)或64 | _metadata,指向class对象 |
内存地址 | "小明"oop对象指针 |
内存地址 | 18,int类型数值 |
那么整个对象的大小包括了oop对象头大小为12字节(压缩)+成员变量1+成员变量2..,其中包括父类的成员变量的值,不包括static变量的值(static变量保存在class的java_mirror属性中)
如果新建一个oop对象,分配内存需要计算oop大小,那么oop的size()实际上是取值oop对应的元对象class的_layout_helper 的大小
贴一个class对象
(gdb) p k $87 = (InstanceKlass *) 0x100060030 (gdb) p * k $88 = (InstanceKlass) { <Klass> = { <Metadata> = { <MetaspaceObj> = {<No data fields>}, members of Metadata: _vptr.Metadata = 0x7f5aa945e590 <vtable for InstanceKlass+16>, _valid = 0 }, members of Klass: _layout_helper = 24, _super_check_offset = 56, _name = 0x7f5aa014b5d8, _secondary_super_cache = 0x0, _secondary_supers = 0x7f5aa5399090, _primary_supers = {0x100000f30, 0x100060030, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, _java_mirror = 0xd758fc70, _super = 0x100000f30, _subklass = 0x0, _next_sibling = 0x1000471a8, _next_link = 0x0, _class_loader_data = 0x7f5aa0153768, _modifier_flags = 1, _access_flags = { _flags = 2097185 }, _last_biased_lock_bulk_revocation_time = 0, _prototype_header = 0x5, _biased_lock_revocation_count = 0, _modified_oops = 1 '