偶然一次路過同事電腦,看着黑底藍色滿屏的堆棧信息,過去笑着拍了拍他的肩膀說道「小哥,又在寫BUG呢」湊過去仔細看了一眼異常堆棧詳情,「虎軀一震」喲,高端的,這堆棧後面的還有類的包路徑信息呢呢,之前看堆棧的時候咋沒有特別注意html
坐下打開電腦翻看了下一下Logback的代碼核心計算邏輯ch.qos.logback.classic.spi.PackagingDataCalculator
git
獲取Package
下的MANIFEST.MF
文件裏面Implementation-Version
信息github
和獲取類所在的jar
包路徑
能夠看到全部的信息都在類對應的Class對象上併發
不少時候爲了解決Maven扁平化依賴臃腫和依賴衝突問題,咱們每每會用上類隔離框架,好比說支付寶開源的sofa-ark,其基本原理就是使用單獨的ClassLoader
加載,而且將一部門類EXPORT
,假設若是遇到沒有被EXPORT
出來的類(幽靈Class),會發生什麼狀況呢?app
由於是屬於沒有被EXPORT
出來的類因此最終會委託給應用類加載器加載框架
爲了防止重複加載,因此應用類加載器在加載類的時候會根據加載的className
加鎖,由於類也不是應用類加載器加載的因此會進行雙親委派加載,最後拋出ClassNotFoundException
,再結合PackagingDataCalculator
對異常的處理
程序不會終止,因此咱們能夠得出結論只要碰到「幽靈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...日誌