1、oopDesc::oop_iterate/ oopDesc::oop_iterate_backwards
2、Klass::oop_oop_iterate / Klass::oop_oop_iterate_backwards
之前的博客在讲解GC引用遍历时最终都会碰到oopDesc::oop_iterate这个方法,用来遍历该对象所引用的其他对象,本篇博客就来详细探讨这个关键方法的实现。
1、oopDesc::oop_iterate/ oopDesc::oop_iterate_backwards
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的相关方法。
2、Klass::oop_oop_iterate / Klass::oop_oop_iterate_backwards
这两组方法的定义方式跟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类内存表示机制》,下面逐一讲解各子类的实现。
3、InstanceKlass
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_