Java检查子类型关系的实现

Java代码中经常涉及到的是检查两个类之间的继承关系,因此其实现方式将会对程序的整体性能代码较大影响。

A instanceof B
来说,最简单的实现方式是将父类、父接口放在一维数组中,再遍历一遍。这种方式实现简单,但是性能不咋地。

在hotspot中的实现方式是将父类和父接口区分开,较深的继承关系和较浅的继承关系区分开,针对”较浅的父类继承”做优化,其余情况(接口继承和较深的父类继承)则通过线性扫描处理:

Object

在扫描子类的完整继承树之前,可以做一些优化判断,剔除明显不需要扫描继承树的情况

  1. B
    本身的继承深度浅,且 A
    没有继承 B
  2. A
    == B

除却以上情况,再进行完整继承树的扫描。这种处理方式,能够较好的应对绝大部分应用场景。第2种情况好说,下面专门说说第1种情况。

从具体实现上看,hotspot定义了两种类型:

  • restricted primary class

    • T
      表示
      原生类型数组
      原生类型包装类数组
      数组时,并且 T
      的继承树深度小于 指定阈值
      时,则称 T
      restricted primary class
  • restricted secondary type
    :
    • 除了 restricted primary class
      之外的,都是 restricted secondary type

定义类的数据结构如下(这里去掉了与本主题无关的字段):

jint _primary_super_limit = 8

class Klass {
    juint           _super_check_offset;        
    Klass*          _secondary_super_cache;
    Array<Klass*>*  _secondary_supers;
    Klass*          _primary_supers[_primary_super_limit];
    Klass*          _super;
}

其中变量 _primary_super_limit
表示有限继承树的深度。变量 _super_check_offset
在两种类型下表示不同的含义。

  • restricted primary class
    : 表示当前类型在有限继承树中的索引位置,若不在有限继承树中,则置为 _primary_super_limit
  • restricted secondary type
    : 表示字段 _secondary_super_cache
    相对于当前对象的偏移位置。

假设 A
继承 M
M
继承 Object
,则 A
的继承树如下:

Object  -> 0
M       -> 1
A       -> 2

此时 _super_check_offset
的值为 2

回到前面的问题,若 B
本身的继承深度浅,且 A
没有继承 B
,则可以判断目标类型 _super_check_offset
的值和当前类型的 _secondary_super_cache
偏移是否相同(这个值其实是个编译时常量)。

  • 若不同,则说明 _super_check_offset
    的值表示 B
    在继承树中的索引位置,但由于前面已经判断过 B
    不在 A
    的有限继承树中,因此说明 A
    没有继承自 B
  • 若相同,判断一下 A
    B
    是否相同,若不相同,只能再通过遍历 _secondary_supers
    来判断了。

完整的继承关系判断方法实现如下:

bool is_subtype_of(Klass* k) const {
    juint    off = k->super_check_offset();
    Klass* sup = *(Klass**)( (address)this + off );
    const juint secondary_offset = in_bytes(secondary_super_cache_offset());
    if (sup == k) {
        return true;
    } else if (off != secondary_offset) {
        return false;
    } else {
        return search_secondary_supers(k);
    }
}

Resources

  • Fast subtype checking in the HotSpot JVM
  • Klass.hpp#is_subtype_of

原文 

http://blog.caoxudong.info/blog/2020/03/28/java_subtype_check

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java检查子类型关系的实现

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址