當啓動一個新線程時,JVM就會給這個線程分配一個Java棧(這個棧的內存大小由-Xss
參數來設置)。java
一個Java棧的基本單位是幀,每一次函數調用就會生成棧幀,佔用必定的棧空間。當函數自己須要的內存過大,或者函數調用函數(依賴調用或者遞歸調用)太深,超過了-Xss
設置的內存大小,就會拋出StackOverflowError
異常。函數
-Xss:默認值 1M,控制每一個線程佔用的內存,這個參數決定了函數調用的最大深度。若是設置的過小可能會很容易出現 StackOverflowError 異常。JDK 5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K。在相同物理內存下,減少這個值能生成更多的線程。可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成,經驗值在3000~5000左右。工具
public class StackOverflow { private static int deep = 1; /** * 經過無限遞歸來模擬棧溢出 */ private static void recursion() { deep++; recursion(); } public static void main(String[] args) { try { recursion(); } catch (Throwable e) { // catch 捕獲的是 Throwable,而不是 Exception。由於 StackOverflowError 不屬於 Exception 的子類。 System.out.println("Stack deep : " + deep); e.printStackTrace(); } // 不讓進程結束,便於使用分析工具來查看內存狀況 try { Thread.sleep(24 * 60 * 60 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
執行結果操作系統
Stack deep : 11429 java.lang.StackOverflowError at com.song.StackOverflow.call(StackOverflow.java:16) at com.song.StackOverflow.call(StackOverflow.java:17) ...