赞
踩
1、oopDesc::oop_iterate/ oopDesc::oop_iterate_backwards
2、Klass::oop_oop_iterate / Klass::oop_oop_iterate_backwards
之前的博客在讲解GC引用遍历时最终都会碰到oopDesc::oop_iterate这个方法,用来遍历该对象所引用的其他对象,本篇博客就来详细探讨这个关键方法的实现。
oopDesc定义的oop遍历的方法主要就上述两个,oop_iterate有两个版本,一个只有一个参数OopClosure,另外一个有两个参数,OopClosure和MemRegion。这两方法都是通过宏定义的,位于hotspot\src\share\vm\oops\oop.hpp中,如下:
- #define OOP_ITERATE_DECL(OopClosureType, nv_suffix) \
- int oop_iterate(OopClosureType* blk); \
- int oop_iterate(OopClosureType* blk, MemRegion mr); // Only in mr.
-
- //ALL_OOP_OOP_ITERATE_CLOSURES_1用来定义具体的OopClosureType
- //OOP_ITERATE_DECL就是定义具体的方法
- ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DECL)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DECL)
-
- #if INCLUDE_ALL_GCS
-
- #define OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
- int oop_iterate_backwards(OopClosureType* blk);
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DECL)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DECL)
- #endif
这两方法的实现在同目录下的oop.inline.hpp中,如下:
-
- #define OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
- \
- inline int oopDesc::oop_iterate(OopClosureType* blk) { \
- SpecializationStats::record_call(); \
- return klass()->oop_oop_iterate##nv_suffix(this, blk); \
- } \
- \
- inline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) { \
- SpecializationStats::record_call(); \
- return klass()->oop_oop_iterate##nv_suffix##_m(this, blk, mr); \
- }
-
- //ALL_OOP_OOP_ITERATE_CLOSURES_1定义具体的OopClosureType
- ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
-
- #define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
- \
- inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) { \
- SpecializationStats::record_call(); \
- return klass()->oop_oop_iterate_backwards##nv_suffix(this, blk); \
- }
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DEFN)
oopDesc的其他几个子类可以参考《Hotspot Oop模型——Java对象内存表示机制》,其他子类没有覆写父类oopDesc的oop_iterate方法的实现,只有表示对象数组的objArrayOopDesc新增了一个oop_iterate_range方法,定义在同目录的objArrayOop.hpp中,如下:
其实现在在同目录的objArrayOop.cpp中,如下:
即oopDesc的引用遍历方法底层都是调用Klass的相关方法。
这两组方法的定义方式跟oopDesc是一样的,定义在同目录的klass.hpp中,如下:
- //oopDesc::oop_iterate对应的两个方法
- define Klass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \
- virtual int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk) { \
- /* Default implementation reverts to general version. */ \
- return oop_oop_iterate(obj, blk); \
- } \
- \
- virtual int oop_oop_iterate##nv_suffix##_m(oop obj, \
- OopClosureType* blk, \
- MemRegion mr) { \
- return oop_oop_iterate_m(obj, blk, mr); \
- }
-
- //同样,SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1用来定义具体类型的OopClosureType
- SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_DECL)
- SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_DECL)
-
- #if INCLUDE_ALL_GCS
- //oopDesc::oop_iterate_backwards对应的方法实现
- #define Klass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
- virtual int oop_oop_iterate_backwards##nv_suffix(oop obj, \
- OopClosureType* blk) { \
- /* Default implementation reverts to general version. */ \
- return oop_oop_iterate_backwards_v(obj, blk); \
- }
-
- SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
- SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
- #endif // INCLUDE_ALL_GCS
在Eclipse中点击oop_oop_iterate方法的实现如下:
即不同的Klass子类都有自己的实现版本,其中Klass的实现是一个虚方法,空实现。oop_oop_iterate_m和oop_oop_iterate_backwards_v的实现都一样取决于子类。Klass的各子类的说明参考《Hotspot Klass模型——Java类内存表示机制》,下面逐一讲解各子类的实现。
InstanceKlass用于表示普通的Java类,该类重定义了oop_oop_iterate和oop_oop_iterate_backwards方法,如下:
这里用于表示具体的OopClosureType的宏跟oopDesc中使用的宏是一样的,即跟oopDesc中定义的方法是能一一对应的,其实现如下:
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN)
-
- #define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
- \
- int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
- /* header */ \
- if_do_metadata_checked(closure, nv_suffix) { \
- //如果需要检查Klass,则遍历该klass
- closure->do_klass##nv_suffix(obj->klass()); \
- } \
- InstanceKlass_OOP_MAP_ITERATE( \
- obj, \
- SpecializationStats:: \
- record_do_oop_call##nv_suffix(SpecializationStats::ik); \
- (closure)->do_oop##nv_suffix(p), \//注意这里是两个方法作为参数do_oop传入到宏中的
- assert_is_in_closed_subset) \
- return size_helper(); \
- }
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
-
- #define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
- \
- int InstanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj, \
- OopClosureType* closure, \
- MemRegion mr) { \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
- if_do_metadata_checked(closure, nv_suffix) { \
- if (mr.contains(obj)) { \
- //如果需要检查Klass,则遍历该klass
- closure->do_klass##nv_suffix(obj->klass()); \
- } \
- } \
- InstanceKlass_BOUNDED_OOP_MAP_ITERATE( \
- obj, mr.start(), mr.end(), \
- (closure)->do_oop##nv_suffix(p), \
- assert_is_in_closed_subset) \
- return size_helper(); \
- }
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-
- #define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
- \
- int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, \
- OopClosureType* closure) { \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \
- //校验closure的do_metadata方法返回false \
- assert_should_ignore_metadata(closure, nv_suffix); \
- \
- /* instance variables */ \
- InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
- obj, \
- SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::ik);\
- (closure)->do_oop##nv_suffix(p), \
- assert_is_in_closed_subset) \
- return size_helper(); \
- }
-
- #define if_do_metadata_checked(closure, nv_suffix) \
- /* Make sure the non-virtual and the virtual versions match. */ \
- assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
- "Inconsistency in do_metadata"); \
- if (closure->do_metadata##nv_suffix()) //判断是否需要检查klass
-
- //返回该对象的大小
- int size_helper() const {
- return layout_helper_to_size_helper(layout_helper());
- }
-
- #define assert_should_ignore_metadata(closure, nv_suffix) \
- assert(!closure->do_metadata##nv_suffix(), "Code to handle metadata is not implemented")
-
- #define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn) \
- { \
- /*计算包含所引用的oop的起止范围*/ \
- OopMapBlock* map = start_of_nonstatic_oop_maps(); \
- OopMapBlock* const end_map = map + nonstatic_oop_map_count(); \
- if (UseCompressedOops) { \
- while (map < end_map) { \
- InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
- obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \
- do_oop, assert_fn) \
- ++map; \
- } \
- } else { \
- //注意外层是遍历OopMapBlock
- while (map < end_map) { \
- //InstanceKlass_SPECIALIZED_OOP_ITERATE遍历某个Map内包含的oop
- InstanceKlass_SPECIALIZED_OOP_ITERATE(oop, \
- //map->offset()返回第一个引用类型属性相当于当前oop的偏移量
- //map->count()返回该Map包含的oop的个数
- obj->obj_field_addr<oop>(map->offset()), map->count(), \
- do_oop, assert_fn) \
- ++map; \
- } \
- } \
- }
-
- //返回当前Klass的OopMapBlock的起始位置,itable的起始地址加上itable的长度就是OopMapBlock的起始地址了
- OopMapBlock* start_of_nonstatic_oop_maps() const {
- return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length()));
- }
-
- //返回vtable的起始问题
- intptr_t* start_of_vtable() const { return ((intptr_t*)this) + vtable_start_offset(); }
-
- //vtable的起始位置加上vtable的长度就是itable的起始地址了
- intptr_t* start_of_itable() const { return start_of_vtable() + align_object_offset(vtable_length()); }
-
- //返回包含的OopMapBlock的个数
- unsigned int nonstatic_oop_map_count() const {
- return _nonstatic_oop_map_size / OopMapBlock::size_in_words();
- }
-
- //获取相当于当前oop地址指定偏移量的属性地址
- template <class T> inline T* oopDesc::obj_field_addr(int offset) const { return (T*)field_base(offset); }
-
- inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; }
-
-
- #define InstanceKlass_SPECIALIZED_OOP_ITERATE( \
- T, start_p, count, do_oop, \
- assert_fn) \
- { \
- T* p = (T*)(start_p); \
- T* const end = p + (count); \
- //遍历指定范围的oop
- while (p < end) { \
- (assert_fn)(p); \
- do_oop; \
- ++p; \
- } \
- }
-
- //low和high就是MemRegion的起始位置
- #define InstanceKlass_BOUNDED_OOP_MAP_ITERATE(obj, low, high, do_oop, \
- assert_fn) \
- { \
- OopMapBlock* map = start_of_nonstatic_oop_maps(); \
- OopMapBlock* const end_map = map + nonstatic_oop_map_count(); \
- if (UseCompressedOops) { \
- while (map < end_map) { \
- InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
- obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \
- low, high, \
- do_oop, assert_fn) \
- ++map; \
- } \
- } else { \
- while (map < end_map) { \
- InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \
- obj->obj_field_addr<oop>(map->offset()), map->count(), \
- low, high, \
- do_oop, assert_fn) \
- ++map; \
- } \
- } \
- }
-
- #define InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
- T, start_p, count, low, high, \
- do_oop, assert_fn) \
- { \
- T* const l = (T*)(low); \
- T* const h = (T*)(high); \
- //校验l和h都是按照T的大小的整数倍,即已经内存对齐了
- assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
- mask_bits((intptr_t)h, sizeof(T)-1) == 0, \
- "bounded region must be properly aligned"); \
- T* p = (T*)(start_p); \
- T* end = p + (count); \
- //计算遍历对象的地址范围
- if (p < l) p = l; \
- if (end > h) end = h; \
- while (p < end) { \
- (assert_fn)(p); \
- do_oop; \
- ++p; \
- } \
- }
-
- //注意跟InstanceKlass_OOP_MAP_ITERATE相比,此处从外层都内层都是从高地址往低地址反向遍历
- #define InstanceKlass_OOP_MAP_REVERSE_ITERATE(obj, do_oop, assert_fn) \
- { \
- OopMapBlock* const start_map = start_of_nonstatic_oop_maps(); \
- OopMapBlock* map = start_map + nonstatic_oop_map_count(); \
- if (UseCompressedOops) { \
- while (start_map < map) { \
- --map; \
- InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(narrowOop, \
- obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \
- do_oop, assert_fn) \
- } \
- } else { \
- while (start_map < map) { \
- --map; \
- InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(oop, \
- obj->obj_field_addr<oop>(map->offset()), map->count(), \
- do_oop, assert_fn) \
- } \
- } \
- }
-
- //注意此方法是从高地址往地址反向遍历
- #define InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE( \
- T, start_p, count, do_oop, \
- assert_fn) \
- { \
- T* const start = (T*)(start_p); \
- T* p = start + (count); \
- while (start < p) { \
- --p; \
- (assert_fn)(p); \
- do_oop; \
- } \
- }
从上述实现可知每个oop的vtable的后面都包含有若干个OopMapBlock,每个OopMapBlock都保存了若干个oop,InstanceKlass的oop_oop_iterate方法实际就是遍历所有OopMapBlock中包含的oop。
OopMapBlock是一个简单的内嵌在Klass里面的数据结构,用来描述oop中包含的引用类型属性,即该oop所引用的其他oop在oop中的内存分布,然后就可以根据当前oop的地址找到所有引用的其他oop了,其定义如下:
其中offset描述第一个所引用的oop相对于当前oop地址的偏移量,count表示包含的oop的个数,注意这里的包含并不是指这些oop位于OopMapBlock里面,而是有count个连续存放的oop。为啥会有多个OopMapBlock了?因为每个OopMapBlock只能描述当前子类中包含的引用类型属性,父类的引用类型属性由单独的OopMapBlock描述,下面我们用HSDB来实际探查下,HSDB的使用可以参考《Hotspot学习利器:HSDB和CLHSDB》。测试用例如下:
- package jvmTest;
-
- import java.lang.management.ManagementFactory;
- import java.lang.management.RuntimeMXBean;
-
- class Base{
- private int a=1;
-
- private String s="abc";
-
- private Integer a2=12;
-
- private int a3=22;
- }
-
- class A extends Base {
- private int b=3;
-
- private String s2="def";
-
- private int b2=33;
-
- private Base a=new Base();
- }
-
- class B extends A{
- private String s3="ghk";
-
- private Integer c=4;
-
- private int c2=44;
- }
-
- public class MainTest {
-
- public static void main(String[] args) {
- Base a=new Base();
- A a2=new A();
- B b=new B();
- while (true){
- try {
- System.out.println(getProcessID());
- Thread.sleep(600*1000);
- } catch (Exception e) {
-
- }
- }
- }
-
- public static final int getProcessID() {
- RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
- System.out.println(runtimeMXBean.getName());
- return Integer.valueOf(runtimeMXBean.getName().split("@")[0])
- .intValue();
- }
- }
运行main方法后,用HSDB查看main线程的线程栈,从中找出变量a,a2,b对应的oop的地址,如下:
分别查看0x00000000d69d98a0,0x00000000d69db5f8,0x00000000d69dd070对应的oop,如下:
上从面的截图可知,子类会完整的保留父类的属性,从而方便调用父类方法时能够正确的使用父类的属性。上述对oop的属性打印是按照类声明属性的顺序来的,内存中是这样保存的么?可以通过查看属性的偏移量来判断。
在Class Browser中搜索jvmTest,可以查找到我们三个自定义类对应的Klass,如下图:
分别点击这三个类查看属性的偏移量,如下:
根据上述偏移量,我们可以得出jvmTest.B对象的内存布局,如下:
int本身占4个字节,引用类型属性本质上就是一个指针,这里因为默认开启了指针压缩,所以也是4字节。
我们再看下表示OopMapBlock在Klass中的字宽数的属性_nonstatic_oop_map_size在三个类中的取值,如下:
OopMapBlock本身就只有两个int属性,所以一个OopMapBlock实例只有8字节,即一个字宽,jvmTest.B的_nonstatic_oop_map_size属性值为3,即由3个OopMapBlock,下面通过CHSDB的mem命令来看看这3个OopMapBlock对应的内存数据。
首先执行inspect对象得到该Klass本身的大小,即sizeof的大小,如下:
vtable,itable,OopMapBlock这三个都是内嵌在Klass里面的,所谓的内嵌实际是指这块内存是紧挨着Klass自身的属性对应的内存的下面,从上一节的分析可知,OopMapBlock在itable的后面,itable在vtable的后面,而vtable是紧挨着Klass的,从上述inspect命令的输出,也可知道itable和vtable的内存大小,单位是字宽,如下:
因此OopMapBlock的起始地址就是Klass的地址加上Klass本身的大小440字节即55字宽,再加上vtable的5字宽,itable的2字宽,总共加62字宽,OopMapBlock本身占用3个字宽,因此用mem查看这65字宽的数据,如下:
最后的3个字宽如下:
每个字宽对应一个OopMapBlock,前面4字节就是count属性,这里都是2,后面4字节就是offset,分别是20,36,48,与jvmTest.B的内存结构是完全一致的。
InstanceClassLoaderKlass继承自InstanceKlass,用来表示java.lang.ClassLoader及其子类的Klass,该类没有新增其他的属性,主要是改写了引用遍历的方法的实现,增加了对ClassLoaderData的遍历,定义如下:
其实现如下:
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
-
- #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)\
- \
- int InstanceClassLoaderKlass:: \
- oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
- /* Get size before changing pointers */ \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
- int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \
- \
- //如果需要遍历
- if_do_metadata_checked(closure, nv_suffix) { \
- ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj); \
- if (cld != NULL) { \
- //遍历ClassLoaderData
- closure->do_class_loader_data(cld); \
- } \
- } \
- \
- return size; \
- }
-
- //返回ClassLoader oop对应的ClassLoaderData指针
- ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
- return *java_lang_ClassLoader::loader_data_addr(loader);
- }
-
- ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
- assert(loader != NULL && loader->is_oop(), "loader must be oop");
- //_loader_data_offset是一个静态属性,值为-1,即ClassLoaderData指针保存在ClassLoader oop的前一个字节中
- return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset);
- }
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
-
- #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
- \
- int InstanceClassLoaderKlass:: \
- oop_oop_iterate##nv_suffix##_m(oop obj, \
- OopClosureType* closure, \
- MemRegion mr) { \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
- \
- int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \
- \
- if_do_metadata_checked(closure, nv_suffix) { \
- if (mr.contains(obj)) { \
- ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj); \
- if (cld != NULL) { \
- //遍历ClassLoaderData
- closure->do_class_loader_data(cld); \
- } \
- } \
- } \
- \
- return size; \
- }
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-
- #if INCLUDE_ALL_GCS
- #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
- \
- int InstanceClassLoaderKlass:: \
- oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \
- /* Get size before changing pointers */ \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
- int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
- return size; \
- }
- #endif // INCLUDE_ALL_GCS
InstanceMirrorKlass继承自InstanceKlass,用来表示java.lang.Class这个特殊类的Klass,注意java.lang.Class是一个final类,不能被继承。每个类的静态属性就是由该Klass对应的oop来维护的,创建该oop时必须通过InstanceMirrorKlass创建,该类改写了计算oop大小的方法,会把InstanceKlass中保存的静态属性的字宽数(_static_field_size属性)算进来,可通过Klass的_java_mirror属性来访问该oop,注意各种类的Class实例如String.class对应的oop的klass都指向同一个InstanceMirrorKlass实例。Class类实例的创建是通过InstanceMirrorKlass::allocate_instance完成的,该方法的实现如下:
- instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
- //计算实例大小
- int size = instance_size(k);
- KlassHandle h_k(THREAD, this);
- //内存分配
- instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
- //设置实例大小,将size保存到oop中的oop_size字段中
- java_lang_Class::set_oop_size(i, size);
-
- return i;
- }
- int InstanceMirrorKlass::instance_size(KlassHandle k) {
- //校验k是一个非数组类Klass,通过_layout_helper的取值判断,如果是数组,该属性是一个负值
- if (k() != NULL && k->oop_is_instance()) {
- //static_field_size记录该类的静态字段的大小,单位也是字宽
- return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
- }
- return size_helper();
- }
-
- int size_helper() const {
- return layout_helper_to_size_helper(layout_helper());
- }
-
- //_layout_helper保存该类Klass对应的oop的大小,是根据oop包含的对象头和字段属性在class文件解析的时候计算出来的
- int layout_helper() const { return _layout_helper; }
-
- static int layout_helper_to_size_helper(jint lh) {
- assert(lh > (jint)_lh_neutral_value, "must be instance");
- //LogHeapWordSize表示一个字段对应的字节数的log值,64位下是3,这里相当于按8整除
- return lh >> LogHeapWordSize;
- }
-
- int static_field_size() const { return _static_field_size; }
-
- void java_lang_Class::set_oop_size(oop java_class, int size) {
- assert(_oop_size_offset != 0, "must be set");
- java_class->int_field_put(_oop_size_offset, size);
- }
该类主要改写了计算oop大小和引用遍历的相关方法,因为必须考虑类的静态属性。引用遍历的方法定义如下:
其实现如下:
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
-
- #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
- \
- int InstanceMirrorKlass:: \
- oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
- /* Get size before changing pointers */ \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
- \
- //遍历Class实例本身的都有的属性,这些属性是隐藏的,无法通过反射查看并修改
- InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \
- \
- if_do_metadata_checked(closure, nv_suffix) { \
- //获取对应的Klass
- Klass* klass = java_lang_Class::as_Klass(obj); \
- if (klass != NULL) { \
- //遍历Klass,实际就是遍历对应的ClassLoaderData
- closure->do_klass##nv_suffix(klass); \
- } \
- } \
- \
- //遍历静态类型属性
- if (UseCompressedOops) { \
- InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \
- } else { \
- InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \
- } \
- }
-
- Klass* java_lang_Class::as_Klass(oop java_class) {
- //校验该oop是一个java_lang_Class实例
- assert(java_lang_Class::is_instance(java_class), "must be a Class object");
- //获取该Class实例对应的类的Klass,对应的klass实际作为一个隐藏的属性保存在该oop里面
- Klass* k = ((Klass*)java_class->metadata_field(_klass_offset));
- assert(k == NULL || k->is_klass(), "type check");
- return k;
- }
-
- static bool is_instance(oop obj) {
- //Class_klass就是java_lang_Class对一个的Klass,即InstanceMirrorKlass
- return obj != NULL && obj->klass() == SystemDictionary::Class_klass();
- }
-
- #define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(T, nv_suffix) \
- InstanceMirrorKlass_OOP_ITERATE( \
- start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
- (closure)->do_oop##nv_suffix(p), \
- assert_is_in_closed_subset) \
- return oop_size(obj);
-
- //获取静态的引用类型属性在Class实例中的起始地址
- static HeapWord* start_of_static_fields(oop obj) {
- return (HeapWord*)(cast_from_oop<intptr_t>(obj) + offset_of_static_fields());
- }
-
- static int offset_of_static_fields() {
- return _offset_of_static_fields;
- }
-
- //获取包含的静态oop的个数
- int java_lang_Class::static_oop_field_count(oop java_class) {
- assert(_static_oop_field_count_offset != 0, "must be set");
- return java_class->int_field(_static_oop_field_count_offset);
- }
-
- #define InstanceMirrorKlass_OOP_ITERATE(start_p, count, \
- do_oop, assert_fn) \
- { \
- if (UseCompressedOops) { \
- InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
- start_p, count, \
- do_oop, assert_fn) \
- } else { \
- InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(oop, \
- start_p, count, \
- do_oop, assert_fn) \
- } \
- }
-
- //遍历从start_p开始的count个oop
- #define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE( \
- T, start_p, count, do_oop, \
- assert_fn) \
- { \
- T* p = (T*)(start_p); \
- T* const end = p + (count); \
- while (p < end) { \
- (assert_fn)(p); \
- do_oop; \
- ++p; \
- } \
- }
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
-
- #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
- \
- int InstanceMirrorKlass:: \
- oop_oop_iterate##nv_suffix##_m(oop obj, \
- OopClosureType* closure, \
- MemRegion mr) { \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
- \
- InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \
- \
- if_do_metadata_checked(closure, nv_suffix) { \
- if (mr.contains(obj)) { \
- //获取对应的Klass
- Klass* klass = java_lang_Class::as_Klass(obj); \
- if (klass != NULL) { \
- //遍历Klass
- closure->do_klass##nv_suffix(klass); \
- } \
- } \
- } \
- \
- //遍历mr范围内的静态oop
- if (UseCompressedOops) { \
- InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr); \
- } else { \
- InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr); \
- } \
- }
-
- #define InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(T, nv_suffix, mr) \
- InstanceMirrorKlass_BOUNDED_OOP_ITERATE( \
- start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
- mr.start(), mr.end(), \
- (closure)->do_oop##nv_suffix(p), \
- assert_is_in_closed_subset) \
- return oop_size(obj); \
- #define InstanceMirrorKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \
- do_oop, assert_fn) \
- { \
- if (UseCompressedOops) { \
- InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
- start_p, count, \
- low, high, \
- do_oop, assert_fn) \
- } else { \
- InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \
- start_p, count, \
- low, high, \
- do_oop, assert_fn) \
- } \
- }
-
- //跟InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE相比就是多了一个对oop的地址范围的判断,只处理处于该范围内的oop
- #define InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
- T, start_p, count, low, high, \
- do_oop, assert_fn) \
- { \
- T* const l = (T*)(low); \
- T* const h = (T*)(high); \
- assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
- mask_bits((intptr_t)h, sizeof(T)-1) == 0, \
- "bounded region must be properly aligned"); \
- T* p = (T*)(start_p); \
- T* end = p + (count); \
- if (p < l) p = l; \
- if (end > h) end = h; \
- while (p < end) { \
- (assert_fn)(p); \
- do_oop; \
- ++p; \
- } \
- }
-
-
- ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
- ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-
- #define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
- \
- int InstanceMirrorKlass:: \
- oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \
- /* Get size before changing pointers */ \
- SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
- \
- InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
- \
- //遍历静态oop
- if (UseCompressedOops) { \
- InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \
- } else { \
- InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \
- } \
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。