聊聊幽靈Class

原由

偶然一次路過同事電腦,看着黑底藍色滿屏的堆棧信息,過去笑着拍了拍他的肩膀說道「小哥,又在寫BUG呢」湊過去仔細看了一眼異常堆棧詳情,「虎軀一震」喲,高端的,這堆棧後面的還有類的包路徑信息呢呢,之前看堆棧的時候咋沒有特別注意html

坐下打開電腦翻看了下一下Logback的代碼核心計算邏輯ch.qos.logback.classic.spi.PackagingDataCalculatorgit

clipboard.png
獲取Package下的MANIFEST.MF文件裏面Implementation-Version信息github

clipboard.png
和獲取類所在的jar包路徑
能夠看到全部的信息都在類對應的Class對象上併發

深刻思考

不少時候爲了解決Maven扁平化依賴臃腫和依賴衝突問題,咱們每每會用上類隔離框架,好比說支付寶開源的sofa-ark,其基本原理就是使用單獨的ClassLoader加載,而且將一部門類EXPORT,假設若是遇到沒有被EXPORT出來的類(幽靈Class),會發生什麼狀況呢?app

分析

由於是屬於沒有被EXPORT出來的類因此最終會委託給應用類加載器加載框架

clipboard.png

clipboard.png
爲了防止重複加載,因此應用類加載器在加載類的時候會根據加載的className加鎖,由於類也不是應用類加載器加載的因此會進行雙親委派加載,最後拋出ClassNotFoundException,再結合PackagingDataCalculator對異常的處理
clipboard.png程序不會終止,因此咱們能夠得出結論只要碰到「幽靈Class」logback都會從新把類按照雙親委派的方式加載一遍。
有鎖的地方就會有鎖競爭,而且Class.load也是一個耗時的過程,因此同一個ClassName若是併發出如今日誌堆棧中勢必會致使一部分線程會block,這對於線上系統中簡直就是災難.spa

改進

在最近的logback版本中並無發現對ClassNotFoundException的類作特殊處理,而且正如logback官方說的線程

While useful, packaging data is expensive to compute, especially in applications with frequent exceptions.

因此只要logback的版本大於1.1.3,packageDate這個配置默認都是關閉的
https://logback.qos.ch/manual...日誌

相關文章
相關標籤/搜索