当前位置:   article > 正文

Hotspot 垃圾回收之oop_iterate(一) 源码解析_oop_iterate_backwards

oop_iterate_backwards

    目录

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中,如下:

  1. #define OOP_ITERATE_DECL(OopClosureType, nv_suffix) \
  2. int oop_iterate(OopClosureType* blk); \
  3. int oop_iterate(OopClosureType* blk, MemRegion mr); // Only in mr.
  4. //ALL_OOP_OOP_ITERATE_CLOSURES_1用来定义具体的OopClosureType
  5. //OOP_ITERATE_DECL就是定义具体的方法
  6. ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DECL)
  7. ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DECL)
  8. #if INCLUDE_ALL_GCS
  9. #define OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
  10. int oop_iterate_backwards(OopClosureType* blk);
  11. ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DECL)
  12. ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DECL)
  13. #endif

 这两方法的实现在同目录下的oop.inline.hpp中,如下:

  1. #define OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
  2. \
  3. inline int oopDesc::oop_iterate(OopClosureType* blk) { \
  4. SpecializationStats::record_call(); \
  5. return klass()->oop_oop_iterate##nv_suffix(this, blk); \
  6. } \
  7. \
  8. inline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) { \
  9. SpecializationStats::record_call(); \
  10. return klass()->oop_oop_iterate##nv_suffix##_m(this, blk, mr); \
  11. }
  12. //ALL_OOP_OOP_ITERATE_CLOSURES_1定义具体的OopClosureType
  13. ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
  14. ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
  15. #define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
  16. \
  17. inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) { \
  18. SpecializationStats::record_call(); \
  19. return klass()->oop_oop_iterate_backwards##nv_suffix(this, blk); \
  20. }
  21. ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN)
  22. 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中,如下:

  1. //oopDesc::oop_iterate对应的两个方法
  2. define Klass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \
  3. virtual int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk) { \
  4. /* Default implementation reverts to general version. */ \
  5. return oop_oop_iterate(obj, blk); \
  6. } \
  7. \
  8. virtual int oop_oop_iterate##nv_suffix##_m(oop obj, \
  9. OopClosureType* blk, \
  10. MemRegion mr) { \
  11. return oop_oop_iterate_m(obj, blk, mr); \
  12. }
  13. //同样,SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1用来定义具体类型的OopClosureType
  14. SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_DECL)
  15. SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_DECL)
  16. #if INCLUDE_ALL_GCS
  17. //oopDesc::oop_iterate_backwards对应的方法实现
  18. #define Klass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
  19. virtual int oop_oop_iterate_backwards##nv_suffix(oop obj, \
  20. OopClosureType* blk) { \
  21. /* Default implementation reverts to general version. */ \
  22. return oop_oop_iterate_backwards_v(obj, blk); \
  23. }
  24. SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
  25. SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
  26. #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中定义的方法是能一一对应的,其实现如下:

  1. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN)
  2. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN)
  3. #define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
  4. \
  5. int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
  6. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
  7. /* header */ \
  8. if_do_metadata_checked(closure, nv_suffix) { \
  9. //如果需要检查Klass,则遍历该klass
  10. closure->do_klass##nv_suffix(obj->klass()); \
  11. } \
  12. InstanceKlass_OOP_MAP_ITERATE( \
  13. obj, \
  14. SpecializationStats:: \
  15. record_do_oop_call##nv_suffix(SpecializationStats::ik); \
  16. (closure)->do_oop##nv_suffix(p), \//注意这里是两个方法作为参数do_oop传入到宏中的
  17. assert_is_in_closed_subset) \
  18. return size_helper(); \
  19. }
  20. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
  21. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
  22. #define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
  23. \
  24. int InstanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj, \
  25. OopClosureType* closure, \
  26. MemRegion mr) { \
  27. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
  28. if_do_metadata_checked(closure, nv_suffix) { \
  29. if (mr.contains(obj)) { \
  30. //如果需要检查Klass,则遍历该klass
  31. closure->do_klass##nv_suffix(obj->klass()); \
  32. } \
  33. } \
  34. InstanceKlass_BOUNDED_OOP_MAP_ITERATE( \
  35. obj, mr.start(), mr.end(), \
  36. (closure)->do_oop##nv_suffix(p), \
  37. assert_is_in_closed_subset) \
  38. return size_helper(); \
  39. }
  40. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
  41. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
  42. #define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
  43. \
  44. int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, \
  45. OopClosureType* closure) { \
  46. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \
  47. //校验closure的do_metadata方法返回false \
  48. assert_should_ignore_metadata(closure, nv_suffix); \
  49. \
  50. /* instance variables */ \
  51. InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
  52. obj, \
  53. SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::ik);\
  54. (closure)->do_oop##nv_suffix(p), \
  55. assert_is_in_closed_subset) \
  56. return size_helper(); \
  57. }
  58. #define if_do_metadata_checked(closure, nv_suffix) \
  59. /* Make sure the non-virtual and the virtual versions match. */ \
  60. assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
  61. "Inconsistency in do_metadata"); \
  62. if (closure->do_metadata##nv_suffix()) //判断是否需要检查klass
  63. //返回该对象的大小
  64. int size_helper() const {
  65. return layout_helper_to_size_helper(layout_helper());
  66. }
  67. #define assert_should_ignore_metadata(closure, nv_suffix) \
  68. assert(!closure->do_metadata##nv_suffix(), "Code to handle metadata is not implemented")
  69. #define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn) \
  70. { \
  71. /*计算包含所引用的oop的起止范围*/ \
  72. OopMapBlock* map = start_of_nonstatic_oop_maps(); \
  73. OopMapBlock* const end_map = map + nonstatic_oop_map_count(); \
  74. if (UseCompressedOops) { \
  75. while (map < end_map) { \
  76. InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
  77. obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \
  78. do_oop, assert_fn) \
  79. ++map; \
  80. } \
  81. } else { \
  82. //注意外层是遍历OopMapBlock
  83. while (map < end_map) { \
  84. //InstanceKlass_SPECIALIZED_OOP_ITERATE遍历某个Map内包含的oop
  85. InstanceKlass_SPECIALIZED_OOP_ITERATE(oop, \
  86. //map->offset()返回第一个引用类型属性相当于当前oop的偏移量
  87. //map->count()返回该Map包含的oop的个数
  88. obj->obj_field_addr<oop>(map->offset()), map->count(), \
  89. do_oop, assert_fn) \
  90. ++map; \
  91. } \
  92. } \
  93. }
  94. //返回当前Klass的OopMapBlock的起始位置,itable的起始地址加上itable的长度就是OopMapBlock的起始地址了
  95. OopMapBlock* start_of_nonstatic_oop_maps() const {
  96. return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length()));
  97. }
  98. //返回vtable的起始问题
  99. intptr_t* start_of_vtable() const { return ((intptr_t*)this) + vtable_start_offset(); }
  100. //vtable的起始位置加上vtable的长度就是itable的起始地址了
  101. intptr_t* start_of_itable() const { return start_of_vtable() + align_object_offset(vtable_length()); }
  102. //返回包含的OopMapBlock的个数
  103. unsigned int nonstatic_oop_map_count() const {
  104. return _nonstatic_oop_map_size / OopMapBlock::size_in_words();
  105. }
  106. //获取相当于当前oop地址指定偏移量的属性地址
  107. template <class T> inline T* oopDesc::obj_field_addr(int offset) const { return (T*)field_base(offset); }
  108. inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; }
  109. #define InstanceKlass_SPECIALIZED_OOP_ITERATE( \
  110. T, start_p, count, do_oop, \
  111. assert_fn) \
  112. { \
  113. T* p = (T*)(start_p); \
  114. T* const end = p + (count); \
  115. //遍历指定范围的oop
  116. while (p < end) { \
  117. (assert_fn)(p); \
  118. do_oop; \
  119. ++p; \
  120. } \
  121. }
  122. //low和high就是MemRegion的起始位置
  123. #define InstanceKlass_BOUNDED_OOP_MAP_ITERATE(obj, low, high, do_oop, \
  124. assert_fn) \
  125. { \
  126. OopMapBlock* map = start_of_nonstatic_oop_maps(); \
  127. OopMapBlock* const end_map = map + nonstatic_oop_map_count(); \
  128. if (UseCompressedOops) { \
  129. while (map < end_map) { \
  130. InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
  131. obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \
  132. low, high, \
  133. do_oop, assert_fn) \
  134. ++map; \
  135. } \
  136. } else { \
  137. while (map < end_map) { \
  138. InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \
  139. obj->obj_field_addr<oop>(map->offset()), map->count(), \
  140. low, high, \
  141. do_oop, assert_fn) \
  142. ++map; \
  143. } \
  144. } \
  145. }
  146. #define InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
  147. T, start_p, count, low, high, \
  148. do_oop, assert_fn) \
  149. { \
  150. T* const l = (T*)(low); \
  151. T* const h = (T*)(high); \
  152. //校验l和h都是按照T的大小的整数倍,即已经内存对齐了
  153. assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
  154. mask_bits((intptr_t)h, sizeof(T)-1) == 0, \
  155. "bounded region must be properly aligned"); \
  156. T* p = (T*)(start_p); \
  157. T* end = p + (count); \
  158. //计算遍历对象的地址范围
  159. if (p < l) p = l; \
  160. if (end > h) end = h; \
  161. while (p < end) { \
  162. (assert_fn)(p); \
  163. do_oop; \
  164. ++p; \
  165. } \
  166. }
  167. //注意跟InstanceKlass_OOP_MAP_ITERATE相比,此处从外层都内层都是从高地址往低地址反向遍历
  168. #define InstanceKlass_OOP_MAP_REVERSE_ITERATE(obj, do_oop, assert_fn) \
  169. { \
  170. OopMapBlock* const start_map = start_of_nonstatic_oop_maps(); \
  171. OopMapBlock* map = start_map + nonstatic_oop_map_count(); \
  172. if (UseCompressedOops) { \
  173. while (start_map < map) { \
  174. --map; \
  175. InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(narrowOop, \
  176. obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \
  177. do_oop, assert_fn) \
  178. } \
  179. } else { \
  180. while (start_map < map) { \
  181. --map; \
  182. InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(oop, \
  183. obj->obj_field_addr<oop>(map->offset()), map->count(), \
  184. do_oop, assert_fn) \
  185. } \
  186. } \
  187. }
  188. //注意此方法是从高地址往地址反向遍历
  189. #define InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE( \
  190. T, start_p, count, do_oop, \
  191. assert_fn) \
  192. { \
  193. T* const start = (T*)(start_p); \
  194. T* p = start + (count); \
  195. while (start < p) { \
  196. --p; \
  197. (assert_fn)(p); \
  198. do_oop; \
  199. } \
  200. }

从上述实现可知每个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》。测试用例如下:

  1. package jvmTest;
  2. import java.lang.management.ManagementFactory;
  3. import java.lang.management.RuntimeMXBean;
  4. class Base{
  5. private int a=1;
  6. private String s="abc";
  7. private Integer a2=12;
  8. private int a3=22;
  9. }
  10. class A extends Base {
  11. private int b=3;
  12. private String s2="def";
  13. private int b2=33;
  14. private Base a=new Base();
  15. }
  16. class B extends A{
  17. private String s3="ghk";
  18. private Integer c=4;
  19. private int c2=44;
  20. }
  21. public class MainTest {
  22. public static void main(String[] args) {
  23. Base a=new Base();
  24. A a2=new A();
  25. B b=new B();
  26. while (true){
  27. try {
  28. System.out.println(getProcessID());
  29. Thread.sleep(600*1000);
  30. } catch (Exception e) {
  31. }
  32. }
  33. }
  34. public static final int getProcessID() {
  35. RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
  36. System.out.println(runtimeMXBean.getName());
  37. return Integer.valueOf(runtimeMXBean.getName().split("@")[0])
  38. .intValue();
  39. }
  40. }

运行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的遍历,定义如下:

其实现如下:

  1. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
  2. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
  3. #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)\
  4. \
  5. int InstanceClassLoaderKlass:: \
  6. oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
  7. /* Get size before changing pointers */ \
  8. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
  9. int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \
  10. \
  11. //如果需要遍历
  12. if_do_metadata_checked(closure, nv_suffix) { \
  13. ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj); \
  14. if (cld != NULL) { \
  15. //遍历ClassLoaderData
  16. closure->do_class_loader_data(cld); \
  17. } \
  18. } \
  19. \
  20. return size; \
  21. }
  22. //返回ClassLoader oop对应的ClassLoaderData指针
  23. ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
  24. return *java_lang_ClassLoader::loader_data_addr(loader);
  25. }
  26. ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
  27. assert(loader != NULL && loader->is_oop(), "loader must be oop");
  28. //_loader_data_offset是一个静态属性,值为-1,即ClassLoaderData指针保存在ClassLoader oop的前一个字节中
  29. return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset);
  30. }
  31. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
  32. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
  33. #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
  34. \
  35. int InstanceClassLoaderKlass:: \
  36. oop_oop_iterate##nv_suffix##_m(oop obj, \
  37. OopClosureType* closure, \
  38. MemRegion mr) { \
  39. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
  40. \
  41. int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \
  42. \
  43. if_do_metadata_checked(closure, nv_suffix) { \
  44. if (mr.contains(obj)) { \
  45. ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj); \
  46. if (cld != NULL) { \
  47. //遍历ClassLoaderData
  48. closure->do_class_loader_data(cld); \
  49. } \
  50. } \
  51. } \
  52. \
  53. return size; \
  54. }
  55. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
  56. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
  57. #if INCLUDE_ALL_GCS
  58. #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
  59. \
  60. int InstanceClassLoaderKlass:: \
  61. oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \
  62. /* Get size before changing pointers */ \
  63. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
  64. int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
  65. return size; \
  66. }
  67. #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完成的,该方法的实现如下:

  1. instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
  2. //计算实例大小
  3. int size = instance_size(k);
  4. KlassHandle h_k(THREAD, this);
  5. //内存分配
  6. instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
  7. //设置实例大小,将size保存到oop中的oop_size字段中
  8. java_lang_Class::set_oop_size(i, size);
  9. return i;
  10. }
  11. int InstanceMirrorKlass::instance_size(KlassHandle k) {
  12. //校验k是一个非数组类Klass,通过_layout_helper的取值判断,如果是数组,该属性是一个负值
  13. if (k() != NULL && k->oop_is_instance()) {
  14. //static_field_size记录该类的静态字段的大小,单位也是字宽
  15. return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
  16. }
  17. return size_helper();
  18. }
  19. int size_helper() const {
  20. return layout_helper_to_size_helper(layout_helper());
  21. }
  22. //_layout_helper保存该类Klass对应的oop的大小,是根据oop包含的对象头和字段属性在class文件解析的时候计算出来的
  23. int layout_helper() const { return _layout_helper; }
  24. static int layout_helper_to_size_helper(jint lh) {
  25. assert(lh > (jint)_lh_neutral_value, "must be instance");
  26. //LogHeapWordSize表示一个字段对应的字节数的log值,64位下是3,这里相当于按8整除
  27. return lh >> LogHeapWordSize;
  28. }
  29. int static_field_size() const { return _static_field_size; }
  30. void java_lang_Class::set_oop_size(oop java_class, int size) {
  31. assert(_oop_size_offset != 0, "must be set");
  32. java_class->int_field_put(_oop_size_offset, size);
  33. }

该类主要改写了计算oop大小和引用遍历的相关方法,因为必须考虑类的静态属性。引用遍历的方法定义如下:

其实现如下:

  1. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
  2. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
  3. #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
  4. \
  5. int InstanceMirrorKlass:: \
  6. oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
  7. /* Get size before changing pointers */ \
  8. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
  9. \
  10. //遍历Class实例本身的都有的属性,这些属性是隐藏的,无法通过反射查看并修改
  11. InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \
  12. \
  13. if_do_metadata_checked(closure, nv_suffix) { \
  14. //获取对应的Klass
  15. Klass* klass = java_lang_Class::as_Klass(obj); \
  16. if (klass != NULL) { \
  17. //遍历Klass,实际就是遍历对应的ClassLoaderData
  18. closure->do_klass##nv_suffix(klass); \
  19. } \
  20. } \
  21. \
  22. //遍历静态类型属性
  23. if (UseCompressedOops) { \
  24. InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \
  25. } else { \
  26. InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \
  27. } \
  28. }
  29. Klass* java_lang_Class::as_Klass(oop java_class) {
  30. //校验该oop是一个java_lang_Class实例
  31. assert(java_lang_Class::is_instance(java_class), "must be a Class object");
  32. //获取该Class实例对应的类的Klass,对应的klass实际作为一个隐藏的属性保存在该oop里面
  33. Klass* k = ((Klass*)java_class->metadata_field(_klass_offset));
  34. assert(k == NULL || k->is_klass(), "type check");
  35. return k;
  36. }
  37. static bool is_instance(oop obj) {
  38. //Class_klass就是java_lang_Class对一个的Klass,即InstanceMirrorKlass
  39. return obj != NULL && obj->klass() == SystemDictionary::Class_klass();
  40. }
  41. #define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(T, nv_suffix) \
  42. InstanceMirrorKlass_OOP_ITERATE( \
  43. start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
  44. (closure)->do_oop##nv_suffix(p), \
  45. assert_is_in_closed_subset) \
  46. return oop_size(obj);
  47. //获取静态的引用类型属性在Class实例中的起始地址
  48. static HeapWord* start_of_static_fields(oop obj) {
  49. return (HeapWord*)(cast_from_oop<intptr_t>(obj) + offset_of_static_fields());
  50. }
  51. static int offset_of_static_fields() {
  52. return _offset_of_static_fields;
  53. }
  54. //获取包含的静态oop的个数
  55. int java_lang_Class::static_oop_field_count(oop java_class) {
  56. assert(_static_oop_field_count_offset != 0, "must be set");
  57. return java_class->int_field(_static_oop_field_count_offset);
  58. }
  59. #define InstanceMirrorKlass_OOP_ITERATE(start_p, count, \
  60. do_oop, assert_fn) \
  61. { \
  62. if (UseCompressedOops) { \
  63. InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
  64. start_p, count, \
  65. do_oop, assert_fn) \
  66. } else { \
  67. InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(oop, \
  68. start_p, count, \
  69. do_oop, assert_fn) \
  70. } \
  71. }
  72. //遍历从start_p开始的count个oop
  73. #define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE( \
  74. T, start_p, count, do_oop, \
  75. assert_fn) \
  76. { \
  77. T* p = (T*)(start_p); \
  78. T* const end = p + (count); \
  79. while (p < end) { \
  80. (assert_fn)(p); \
  81. do_oop; \
  82. ++p; \
  83. } \
  84. }
  85. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
  86. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
  87. #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
  88. \
  89. int InstanceMirrorKlass:: \
  90. oop_oop_iterate##nv_suffix##_m(oop obj, \
  91. OopClosureType* closure, \
  92. MemRegion mr) { \
  93. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
  94. \
  95. InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \
  96. \
  97. if_do_metadata_checked(closure, nv_suffix) { \
  98. if (mr.contains(obj)) { \
  99. //获取对应的Klass
  100. Klass* klass = java_lang_Class::as_Klass(obj); \
  101. if (klass != NULL) { \
  102. //遍历Klass
  103. closure->do_klass##nv_suffix(klass); \
  104. } \
  105. } \
  106. } \
  107. \
  108. //遍历mr范围内的静态oop
  109. if (UseCompressedOops) { \
  110. InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr); \
  111. } else { \
  112. InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr); \
  113. } \
  114. }
  115. #define InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(T, nv_suffix, mr) \
  116. InstanceMirrorKlass_BOUNDED_OOP_ITERATE( \
  117. start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
  118. mr.start(), mr.end(), \
  119. (closure)->do_oop##nv_suffix(p), \
  120. assert_is_in_closed_subset) \
  121. return oop_size(obj); \
  122. #define InstanceMirrorKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \
  123. do_oop, assert_fn) \
  124. { \
  125. if (UseCompressedOops) { \
  126. InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
  127. start_p, count, \
  128. low, high, \
  129. do_oop, assert_fn) \
  130. } else { \
  131. InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \
  132. start_p, count, \
  133. low, high, \
  134. do_oop, assert_fn) \
  135. } \
  136. }
  137. //跟InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE相比就是多了一个对oop的地址范围的判断,只处理处于该范围内的oop
  138. #define InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
  139. T, start_p, count, low, high, \
  140. do_oop, assert_fn) \
  141. { \
  142. T* const l = (T*)(low); \
  143. T* const h = (T*)(high); \
  144. assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
  145. mask_bits((intptr_t)h, sizeof(T)-1) == 0, \
  146. "bounded region must be properly aligned"); \
  147. T* p = (T*)(start_p); \
  148. T* end = p + (count); \
  149. if (p < l) p = l; \
  150. if (end > h) end = h; \
  151. while (p < end) { \
  152. (assert_fn)(p); \
  153. do_oop; \
  154. ++p; \
  155. } \
  156. }
  157. ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
  158. ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
  159. #define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
  160. \
  161. int InstanceMirrorKlass:: \
  162. oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \
  163. /* Get size before changing pointers */ \
  164. SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
  165. \
  166. InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
  167. \
  168. //遍历静态oop
  169. if (UseCompressedOops) { \
  170. InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \
  171. } else { \
  172. InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \
  173. } \
  174. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/456527
推荐阅读
相关标签
  

闽ICP备14008679号