使用 e.printStackTrace() 輸出日誌是怎樣讓系統崩掉的!

知道的越多,不知道的就越多,業餘的像一棵小草!

編輯:業餘草
來源:https://www.xttblog.com/?p=5011

今天,抽個時間,我們換換“口味”,聊一個你可能會經常犯的一個錯誤!使用 e.printStackTrace() 輸出日誌是怎樣讓系統崩掉的!

從方法 printStackTrace 自注釋上來看,該方法是輸出打印異常的堆棧跟蹤信息的。由於,我們從學習 Hello World 的那一天開始,老師就是使用 printStackTrace 輸出錯誤日誌的,導致很多人一直錯誤的使用它並沿用至今!

printStackTrace 嚴重的來說,它可能會導致我們的系統崩潰。因爲,e.printStackTrace() 在打印異常到控制檯時,會將產生錯誤堆棧字符串存入到字符串池內存空間,如果此時的空間比較小,並且異常多,此內存空間可能一下子就被佔滿了,並且有些在此內存空間產出字符串的線程還沒完全生產完整,就沒空間了,導致大量線程產出字符串產出到一半,都等在這了,相互等待,等空閒內存,最終會拋出 OOM,導致整個應用掛掉。

在這種情況下,如果使用 java jvisualvm 來查看內存使用情況,你會發現下圖中最右側的非堆區域,也就是字符串常量池已經滿了!

在接着查看線程信息。

你會發現,大量的線程被卡在了異常輸出的位置。通過具體的行號信息,查看源碼。

確實是 e.printStackTrace() 的鍋。

那麼該怎麼解決呢?

1、提高代碼質量,從源頭解決。先解決爲什麼會拋異常。

2、增加內存,增加非堆內存,增加字符串常量池的內存。

3、禁止使用 e.printStackTrace() 輸出日誌。

4、提升系統的容錯能力。

除此之外,e.printStackTrace() 是將日誌輸出到控制檯,如果我想將日誌輸出到文件,或者第三方服務器上,它就無能爲力了。而如果你的系統中大量的使用了 e.printStackTrace(),那麼改動的時間和代價就太大了!

另外,也有不少人喜歡使用 System.out.println() 輸出日誌。我也非常不建議,去年我還寫過一篇關於 System.out.println 危險性的文章。不知道大家是否還記得?都 9102 了,你還不知道 System.out.println 的危害!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章