目录

1、oopDesc::oop_iterate/ oopDesc::oop_iterate_backwards

2、Klass::oop_oop_iterate / Klass::oop_oop_iterate_backwards

3、InstanceKlass

4、OopMapBlock

5、InstanceClassLoaderKlass

6、InstanceMirrorKlass


之前的博客在讲解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用来定义具体类型的OopClosureTypeSPECIALIZED_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,则遍历该klassclosure->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,则遍历该klassclosure->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 {                                                               \//注意外层是遍历OopMapBlockwhile (map < end_map) {                                              \//InstanceKlass_SPECIALIZED_OOP_ITERATE遍历某个Map内包含的oopInstanceKlass_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);               \//遍历指定范围的oopwhile (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。

4、OopMapBlock

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的内存结构是完全一致的。

5、InstanceClassLoaderKlass

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) {                                                          \//遍历ClassLoaderDataclosure->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) {                                                        \//遍历ClassLoaderDataclosure->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

6、InstanceMirrorKlass

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) {                                        \//获取对应的KlassKlass* klass = java_lang_Class::as_Klass(obj);                                    \if (klass != NULL) {                                                              \//遍历Klass,实际就是遍历对应的ClassLoaderDataclosure->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,即InstanceMirrorKlassreturn 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)) {                                                           \//获取对应的KlassKlass* klass = java_lang_Class::as_Klass(obj);                                  \if (klass != NULL) {                                                            \//遍历Klassclosure->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);                 \}                                                                                   \
}

Hotspot 垃圾回收之oop_iterate(一) 源码解析相关推荐

  1. Hotspot 垃圾回收之oop_iterate(二) 源码解析

    目录 1.java.lang.Class 1.1.Class实例中oop_size.klass等属性是哪来的? 1.2._offset_of_static_fields 1.3 为什么从_offset ...

  2. Hotspot 对象引用Reference和Finalizer 源码解析

    目录 一.Reference 1.SoftReference / WeakReference / PhantomReference 2.定义 3.ReferenceHandler 4.Cleaner ...

  3. Hotspot 垃圾回收之GenCollectedHeap 源码解析

    目录 1.定义 2.构造方法 / initialize / post_initialize 3.do_collection 4.do_full_collection 5.collect 6.VM_Ge ...

  4. Hotspot 垃圾回收之ReferenceProcessor(二) 源码解析

    目录 1.process_discovered_reflist 2.process_phaseJNI 3.process_discovered_references 4.preclean_discov ...

  5. Hotspot 垃圾回收之VM_Operation 源码解析

    目录 一.VM_Operation ​二.VMThread 1.定义 2.create / destroy 3.run / wait_for_vm_thread_exit 4.loop 5.VMThr ...

  6. 小程序源码:登录已修复零象垃圾废品回收微信小程序源码下载,V2.8.2完整全开源前端+后端

    零象垃圾废品回收小程序源码,V2.8.2完整全开源安装包+小程序前端, 是一款专注于垃圾回收小程序源码,支持协议定期企业废品回收,垃圾分类小区物业定期回收. 关于程序 运行环境:微擎+PHP+MYSQ ...

  7. Hotspot 重量级锁ObjectMonitor(一) 源码解析

    目录 1.定义 2.TrySpin_VaryDuration 3.ObjectWaiter 4.EnterI 5.JavaThreadBlockedOnMonitorEnterState / OSTh ...

  8. Hotspot 重量级锁ObjectMonitor(二) 源码解析

    目录 1.AddWaiter / DequeueWaiter /DequeueSpecificWaiter 2.wait 3.notify 4.notifyAll 5.exit 6.try_enter ...

  9. JAVA计算机毕业设计二手手机回收平台系统Mybatis+源码+数据库+lw文档+系统+调试部署

    JAVA计算机毕业设计二手手机回收平台系统Mybatis+源码+数据库+lw文档+系统+调试部署 JAVA计算机毕业设计二手手机回收平台系统Mybatis+源码+数据库+lw文档+系统+调试部署 本源 ...

最新文章

  1. 再谈应用环境下的TIME_WAIT和CLOSE_WAIT
  2. matlab ac电源,基于MATLAB对AC/DC/AC电源的死区效应的谐波分析及仿真
  3. charles都踩过哪些坑_开水果店的你,踩过了哪些坑?
  4. 360 屏蔽ajax,怎么在easy ui做全局Ajax拦截啊?
  5. php员工积分绩效,详解绩效积分奖励制
  6. matlab 转换图片格式,Matlab实现图片格式转换 pgm转jpg等
  7. data 的数据代理
  8. php--- 转换编码
  9. 如何写出一个较好的快速排序程序
  10. java连接设备连接给参数_如何通过蓝牙连接两个设备按参数发送配对代码? JAVA,Android的...
  11. 什么是数据库的三大范式?
  12. MATLAB模式识别基本操作函数解析
  13. ArcView GIS 应用与开发技术(11)-空间分析
  14. integnps 数控智能编程v19.3 数控切割机编程 切割机套料编程
  15. ps的基础知识与教程
  16. 计算机主机mac地址怎么查,怎么查看电脑的Mac地址
  17. baigoStudio baigoSSO v3.0.1(Use CVE-2019-10015.)
  18. CDR教程-使用调和工具制作三八天猫标志
  19. 三大运营商的网上流量卡数据对比,看看你会选哪一个?
  20. 微PE工具箱增加安装Linux/Ubuntu/Centos/deepin系统菜单

热门文章

  1. 温度计:不用水银,或者不用易碎玻璃,难道就不行?
  2. LeetCode 461. 汉明距离
  3. c语言100w数据排序需要多久,验证:如何快速插入100w数据
  4. linux密码忘了?一招解决
  5. 科研试剂5,10,15,20-四(4-羟基苯)-21H,23H-卟啉(51094-17-8);铕配合物Eu-pyP;5-对-(对羰基苯甲酸)-氨基苯基-10,1 5,20-三苯基卟啉铜Cu(p-CP
  6. 启用Microsoft loopback Adapte
  7. 最新微信漏洞曝光:利用微信群邮件日吸过万精准流量
  8. C++ TGP 模板基础知识--01函数模板
  9. 22第十一章:【01】进程管理
  10. java抓取并保存图片_利用JAVA抓取网站的所有图片并保存于本地