OpenJDK中的JVM_GetClassDeclaredMethods方法返回順序

這幾天有同事問到,在junit的一些資料中,為什么不推薦使用@FixMethodOrder(MethodSorters.JVM)來做執(zhí)行方法排序。

對(duì)于這個(gè)問題,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

 */

也就是說在每次被加載運(yùn)行時(shí),順序是不確定的。

稍做一下分析,可以看出這個(gè)問題本質(zhì)上是Class類中

getDeclaredMethods0這個(gè)本地方法返回的順序問題。

private native Method[] getDeclaredMethods0(boolean publicOnly);

之前某項(xiàng)目在做webservice測(cè)試時(shí)也提到過類似的問題(運(yùn)行時(shí)環(huán)境略有不同,是在J9上跑的,不過本質(zhì)上沒有什么差別),因此把這個(gè)問題拿來總結(jié)一下,以下代碼為OpenJDK 8u最新版本。

由于函數(shù)內(nèi)容較長(zhǎng),以幾張關(guān)鍵代碼的圖來說明分析過程:

  1. 方法入口
image.png
  1. 這里訪問了k->methods(),->操作符在instanceKlassHandler中被重載了,看起來比較繞
image.png
  1. 真實(shí)調(diào)用的是
image.png
  1. set_methods在類加載的時(shí)候被調(diào)用
image.png
  1. 在set_methods之前,有一個(gè)比較重要的地方,對(duì)方法進(jìn)行了排序,這個(gè)順序決定了最終的返回結(jié)果
image.png
  1. 關(guān)注一下method_comparator
image.png
  1. 最初以為是按照方法的name進(jìn)行排序,結(jié)論和之前的現(xiàn)象不符(如果按照name排序,那么肯定是固定的),后來發(fā)現(xiàn)name其實(shí)是一個(gè)Symbol
image.png
  1. 繼續(xù)關(guān)注上面的fast_compare函數(shù),排序邏輯如下
image.png
  1. 到這里基本可以解釋為什么MethodSorters.JVM是一個(gè)亂序了,這里比較的是地址,Symbol在傳統(tǒng)意義的c堆中分配,因此無法保證每次獨(dú)立運(yùn)行時(shí)的先后順序
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容