美文网首页
OpenJDK中的JVM_GetClassDeclaredMet

OpenJDK中的JVM_GetClassDeclaredMet

作者: ssssssnake | 来源:发表于2017-12-18 15:28 被阅读0次

    这几天有同事问到,在junit的一些资料中,为什么不推荐使用@FixMethodOrder(MethodSorters.JVM)来做执行方法排序。

    对于这个问题,API中的说法如下:

    /**

     * Leaves the test methods in the order returned by the JVM.
    
     * Note that the order from the JVM may vary from run to run
    
     */
    

    也就是说在每次被加载运行时,顺序是不确定的。

    稍做一下分析,可以看出这个问题本质上是Class类中

    getDeclaredMethods0这个本地方法返回的顺序问题。

    private native Method[] getDeclaredMethods0(boolean publicOnly);

    之前某项目在做webservice测试时也提到过类似的问题(运行时环境略有不同,是在J9上跑的,不过本质上没有什么差别),因此把这个问题拿来总结一下,以下代码为OpenJDK 8u最新版本。

    由于函数内容较长,以几张关键代码的图来说明分析过程:

    1. 方法入口
    image.png
    1. 这里访问了k->methods(),->操作符在instanceKlassHandler中被重载了,看起来比较绕
    image.png
    1. 真实调用的是
    image.png
    1. set_methods在类加载的时候被调用
    image.png
    1. 在set_methods之前,有一个比较重要的地方,对方法进行了排序,这个顺序决定了最终的返回结果
    image.png
    1. 关注一下method_comparator
    image.png
    1. 最初以为是按照方法的name进行排序,结论和之前的现象不符(如果按照name排序,那么肯定是固定的),后来发现name其实是一个Symbol
    image.png
    1. 继续关注上面的fast_compare函数,排序逻辑如下
    image.png
    1. 到这里基本可以解释为什么MethodSorters.JVM是一个乱序了,这里比较的是地址,Symbol在传统意义的c堆中分配,因此无法保证每次独立运行时的先后顺序

    相关文章

      网友评论

          本文标题:OpenJDK中的JVM_GetClassDeclaredMet

          本文链接:https://www.haomeiwen.com/subject/eqdmwxtx.html