最先在騰訊Matrix中遇到這個編譯問題, 當時認爲是首包方法數超過了65536.
然而, 不斷精簡首包方法數依然不能解決. 因此確認和方法數無關.沒法解決, 只得放棄使用騰訊Matrixjava
使用ASM開發自研的插件, 也遇到一樣的"stack overflow"問題, 致使編譯失敗. 問題報錯以下:
數組
既然是自研的代碼, 有足夠的自由空間, 那必定能夠着手解決這個問題.jvm
根據異常堆棧提示, 在"ExecutionStack.java:168"位置拋出異常:
學習
看起來, 是由於某個計算的結果值超過了stack.length. 就主動拋出了異常"overflow"gradle
那麼這個stack是什麼? 其length是從哪裏來的?
繼續跟代碼可知是ExecutionStack初始化是給到的:
插件
繼續翻代碼, 發現這段:
3d
(int maxLocals, int maxStack)
有點眼熟:
ASM裏注入方法時的
這個visitMaxs方法, 參數名一致, 彷佛問題就是出在這裏. 可是還須要驗證.
首先, visitMaxs()是在ASM中的, 而ExecutionStack是gradle中的, 二者來源其實並不一樣.
順代碼梳理, 應該很花時間. 簡單網搜了下, 都和jvm的==方法棧長度==有關, 看起來有點聯繫.code
其次, gradle的源碼是不能改的, 深刻的學習jvm得花點時間.
只有ASM的這個visitMaxs()方法, 咱們能夠重寫. 那就從visitMaxs()入手吧
重寫visitMaxs()的關鍵就是傳入正確的maxStack, 和maxLocals. 那麼==問題的關鍵就是如何正確傳入這兩個值==
使用AS的ASM Bytecode Outline插件能夠查看java文件的字節碼, 以此確認正確的值: cdn
確認值以後重寫visitMaxs()方法:
blog
嘗試編譯, 成功!
解決後總結根本緣由:
PS: 另外還有一種狀況, 也是visitMaxs()傳入的參數不正確致使的:
經驗上看, 利用ASM插樁碰到和數組長度相關的編譯異常, 能夠優先確認visitMaxs()傳入的值是否正確.