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

    目录

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用来定义具体类型的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_
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值