1. 程式人生 > >線程棧溢出與線程屬性

線程棧溢出與線程屬性

數據 int 地址 這不 log thread 空間 bsp tail

http://blog.csdn.net/qq_27231343/article/details/52562196

那麽過多的遞歸調用為什麽會引起棧溢出呢?事實上,函數調用的參數是通過棧空間來傳遞的,在調用過程中會占用線程的棧資源。而遞歸調用,只有走到最後的結束點後函數才能依次退出,而未到達最後的結束點之前,占用的棧空間一直沒有釋放,如果遞歸調用次數過多,就可能導致占用的棧資源超過線程的最大值,從而導致棧溢出,導致程序的異常退出。

http://blog.csdn.net/luqiang454171826/article/details/6133972

1,什麽是棧溢出?

因為棧一般默認為1-2m,一旦出現死循環或者是大量的遞歸調用,在不斷的壓棧過程中,造成棧容量超過1m而導致溢出。

2,解決方案:

方法一:用棧把遞歸轉換成非遞歸

通常,一個函數在調用另一個函數之前,要作如下的事情:a)將實在參數,返回地址等信息傳遞給被調用函數保存; b)為被調用函數的局部變量分配存儲區;c)將控制轉移到被調函數的入口. 從被調用函數返回調用函數之前,也要做三件事情:a)保存被調函數的計算結果;b)釋放被調函數的數據區;c)依照被調函數保存的返回地址將控制轉移到調用函數.所有的這些,不論是變量還是地址,本質上來說都是"數據",都是保存在系統所分配的棧中的. 那麽自己就可以寫一個棧來存儲必要的數據,以減少系統負擔。

方法二:使用static對象替代nonstatic局部對象

在遞歸函數設計中,可以使用static對象替代nonstatic局部對象(即棧對象),這不僅可以減少每次遞歸調用和返回時產生和釋放nonstatic對象的開銷,而且static對象還可以保存遞歸調用的中間狀態,並且可為各個調用層所訪問。

方法三:增大堆棧大小值

當創建一個線程的堆棧時,系統將會保留一個鏈接程序的/STACK開關指明的地址空間區域。但是,當調用CreateThread或_beginthreadex函數時,可以重載原先提交的內存數量。這兩個函數都有一個參數,可以用來重載原先提交給堆棧的地址空間的內存數量。如果設定這個參數為0,那麽系統將使用/STACK開關指明的已提交的堆棧大小值。後面將假定我們使用默認的堆棧大小值,即1MB的保留區域,每次提交一個頁面的內存。

Java在創建線程時設置棧大小:thread(threadgroup group, runnable target, string name, long stacksize)
分配新的 thread 對象,以便將 target 作為其運行對象,將指定的 name 作為其名稱,作為 group 所引用的線程組的一員,並具有指定的堆棧大小。

Java虛擬機的堆大小如何設置:命令行

 java –Xms128m //JVM占用最小內存

–Xmx512m //JVM占用最大內存

–XX:PermSize=64m //最小堆大小

–XX:MaxPermSize=128m //最大堆大小

本文來自http://blog.csdn.net/luqiang454171826 ,引用必須註明出處!

線程棧溢出與線程屬性