java.lang.StackOverflowError出現(xiàn)的原因及解決

淺談java.lang.StackOverflowError

StackOverflowError:棧溢出錯(cuò)誤镰惦,如果一個(gè)線程所需用到棧的大小>配置允許最大的棧大小拯杠,那么jvm就會(huì)拋出StackOverflow唇礁。查看一下程序可能是有死循環(huán)或遞歸調(diào)用所產(chǎn)生的,也可以增大JVM的內(nèi)存

棧的特點(diǎn)

1、棧,也叫棧內(nèi)存茬贵,是jvm的內(nèi)存模型之一,每當(dāng)啟動(dòng)一個(gè)新線程的時(shí)候移袍,jvm都會(huì)為它分配一個(gè)java棧解藻。jvm只會(huì)直接對(duì)java棧執(zhí)行兩種操作,以幀為單位的壓棧和出棧葡盗。

image.png

2螟左、棧存儲(chǔ)的內(nèi)容:方法內(nèi)的局部變量表、操作數(shù)觅够、動(dòng)態(tài)鏈接胶背、方法出口信息、其他等信息喘先。

  • 1)局部變量表:保存函數(shù)的參數(shù)以及局部變量用的奄妨,局部變量表中的變量只在當(dāng)前函數(shù)調(diào)用中有效,當(dāng)函數(shù)調(diào)用結(jié)束后苹祟,隨著函數(shù)棧幀的銷毀,局部變量表也會(huì)隨之銷毀评雌。
  • 2)操作數(shù):主要用于保存計(jì)算過程的中間結(jié)果树枫,同時(shí)作為計(jì)算過程中變量臨時(shí)的存儲(chǔ)空間。在概念模型中景东,兩個(gè)棧幀是相互獨(dú)立的砂轻,但是大多數(shù)虛擬機(jī)的實(shí)現(xiàn)都會(huì)進(jìn)行優(yōu)化,令兩個(gè)棧幀出現(xiàn)一部分重疊斤吐,令下面部分的操作數(shù)棧與上面部分的局部變量表重疊在一塊搔涝,這樣在方法調(diào)用的時(shí)候可以共用一部分?jǐn)?shù)據(jù)厨喂,無需進(jìn)行額外的參數(shù)復(fù)制傳遞。
image.png
  • 3)動(dòng)態(tài)鏈接:每個(gè)棧幀都包含一個(gè)指向運(yùn)行時(shí)常量池中該棧幀所屬方法的引用庄呈,持有這個(gè)引用是為了支持方法調(diào)用過程中的動(dòng)態(tài)連接蜕煌。在Class文件的常量池中存有大量的 符號(hào)引用,字節(jié)碼中的方法調(diào)用指令就以常量池中指向方法的符號(hào)引用為參數(shù)诬留。這些符號(hào)引用一部分會(huì)在類加載階段或第一次使用的時(shí)候轉(zhuǎn)化為直接引用斜纪,這種轉(zhuǎn)化 稱為靜態(tài)解析。另外一部分將在每一次的運(yùn)行期期間轉(zhuǎn)化為直接引用文兑,這部分稱為動(dòng)態(tài)連接盒刚。
  • 4)方法出口信息:在方法退出之前,都需要返回到方法被調(diào)用的位置绿贞,程序才能繼續(xù)執(zhí)行因块,方法返回時(shí)可能需要在棧幀中保存一些信息,用來恢復(fù)它的上層方法的執(zhí)行狀態(tài)籍铁,方法出口信息獲取分為正常退出和異常退出涡上。正常退出通過pc計(jì)數(shù)器的值獲取,異常退出通過異常處理器表確定返回地址寨辩。
  • 5)附加信息:虛擬機(jī)規(guī)范中允許具體的虛擬機(jī)實(shí)現(xiàn)增加一些規(guī)范中沒有描述的信息到棧幀中吓懈,這部分信息取決于虛擬機(jī)的實(shí)現(xiàn)。

3靡狞、棧的生命周期:隨著線程的創(chuàng)建而創(chuàng)建耻警,線程的結(jié)束而消亡,釋放內(nèi)存甸怕,所以棧內(nèi)存是私有的

4甘穿、棧的存儲(chǔ)方式:棧內(nèi)存以棧幀(Stack Frame)為單位存儲(chǔ),棧幀是一個(gè)內(nèi)存區(qū)塊梢杭,是一個(gè)有關(guān)方法和運(yùn)行期數(shù)據(jù)的數(shù)據(jù)集温兼。當(dāng)一個(gè)方法M1被調(diào)用的時(shí)候,就會(huì)產(chǎn)生一個(gè)棧幀S1武契,并被壓入到棧中募判,M1方法又調(diào)用了M2方法,這個(gè)時(shí)候又產(chǎn)生棧幀S2也被壓入棧咒唆,M2方法執(zhí)行完畢后届垫,S2棧幀先出棧,S1棧幀再出棧全释,遵循“先進(jìn)后出”原則装处。

出現(xiàn)StackOverflowError的原因分析

一般出現(xiàn)這個(gè)問題是因?yàn)槌绦蚶镉兴姥h(huán)或遞歸調(diào)用所產(chǎn)生的。
如:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //死循環(huán)
    int i=0;
    while (true){
        i++;
        Log.i("ruxing","i="+i);
    }
}
   //遞歸
   private void add(int i){
    i++;
    Log.i("ruxing","i="+i);
    add(i);
  }
}

以遞歸為例浸船,詳解程序:
1)啟動(dòng)MainActivity妄迁,會(huì)創(chuàng)建一個(gè)線程寝蹈,同時(shí)創(chuàng)建一個(gè)棧內(nèi)存。
2)調(diào)用add()方法的時(shí)候登淘,會(huì)對(duì)add()方法進(jìn)行壓棧操作箫老,將add()運(yùn)行期數(shù)據(jù)的數(shù)據(jù)集保存到棧幀中。
3)add()遞歸調(diào)用時(shí)形帮,都會(huì)產(chǎn)生一個(gè)新的棧幀區(qū)塊槽惫,這是就會(huì)連續(xù)的產(chǎn)生新的棧幀區(qū)塊。
4)當(dāng)棧內(nèi)存超過系統(tǒng)配置的棧內(nèi)存辩撑,就會(huì)出現(xiàn)java.lang.StackOverflowError異常界斜。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市合冀,隨后出現(xiàn)的幾起案子各薇,更是在濱河造成了極大的恐慌,老刑警劉巖君躺,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峭判,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡棕叫,警方通過查閱死者的電腦和手機(jī)林螃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俺泣,“玉大人疗认,你說我怎么就攤上這事》疲” “怎么了横漏?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)熟掂。 經(jīng)常有香客問我缎浇,道長(zhǎng),這世上最難降的妖魔是什么赴肚? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任素跺,我火速辦了婚禮,結(jié)果婚禮上誉券,老公的妹妹穿的比我還像新娘亡笑。我一直安慰自己,他們只是感情好横朋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著百拓,像睡著了一般琴锭。 火紅的嫁衣襯著肌膚如雪晰甚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天决帖,我揣著相機(jī)與錄音厕九,去河邊找鬼。 笑死地回,一個(gè)胖子當(dāng)著我的面吹牛扁远,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刻像,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼畅买,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了细睡?” 一聲冷哼從身側(cè)響起谷羞,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎溜徙,沒想到半個(gè)月后湃缎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蠢壹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年嗓违,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片图贸。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹂季,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出求妹,到底是詐尸還是另有隱情乏盐,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布制恍,位于F島的核電站父能,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏净神。R本人自食惡果不足惜何吝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹃唯。 院中可真熱鬧爱榕,春花似錦、人聲如沸坡慌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至跪者,卻和暖如春棵帽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背渣玲。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工逗概, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人忘衍。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓逾苫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親枚钓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子铅搓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容