背景介紹: 項目是微服務的,使用docker容器,使用jenkins部署。測試環境有個公共服務一直以來都能正常發佈,突然有一天不行了,經常發佈失敗,然後多發佈幾次就好了。 報錯如下: 是棧溢出了,一般是新代碼有死迴圈會出現。但是本地啟動沒問題並且環境上多發幾次也能成功,說明沒有死迴圈,肯定是其他原因 ...
背景介紹:
項目是微服務的,使用docker容器,使用jenkins部署。測試環境有個公共服務一直以來都能正常發佈,突然有一天不行了,經常發佈失敗,然後多發佈幾次就好了。
報錯如下:
是棧溢出了,一般是新代碼有死迴圈會出現。但是本地啟動沒問題並且環境上多發幾次也能成功,說明沒有死迴圈,肯定是其他原因。
分析問題:
Java運行時數據區分5部分:
從報錯上來看是虛擬機棧溢出。
虛擬機棧是屬於線程私有的,每個線程都會有一個虛擬機棧,隨線程的創建而創建,消失而消失。它由一個個的棧幀組成,線程每次調用一個方法,就會有一個棧幀生成,並壓棧。方法調用完之後,棧幀則出棧。當棧的深度不夠,即棧的大小不足以放下所有的棧幀的時候,就會拋棧溢出的異常。
問題明確了,是棧的大小不夠。
解決問題:
要把棧大小設置的大一點,要設置的大一點首先要知道目前是多大。項目未對虛擬機棧的大小作設定,也就是說目前的大小是預設值。
JDK5之後每個棧大小是1M,之前是256k。我們用的是JDK8,那麼大小就是1M。要把棧大小設成大於1M的值。但是又不能設置太大,因為如果單個線程棧太大,就會限制最大線程數量。
項目沒有高併發的情況,所以就先設置成2M。設置方法,在JVM啟動參數裡面加上 -Xss2m。
問題解決,再也沒出現過問題。