背景知識(shí):
棧存放什么:棧存儲(chǔ)運(yùn)行時(shí)聲明的變量——對(duì)象引用(或基礎(chǔ)類型, primitive)內(nèi)存空間, 棧的實(shí)現(xiàn)是先入后出的。
堆存放什么:堆分配每一個(gè)對(duì)象內(nèi)容(實(shí)例)內(nèi)存空間。
棧溢出:java.lang.StackOverflowError
堆溢出:java.lang.OutOfMemoryError: Java heap space
棧溢出實(shí)現(xiàn),可以遞歸調(diào)用方法,這樣隨著棧深度的增加,JVM 維持著一條長長的方法調(diào)用軌跡。
堆溢出實(shí)現(xiàn),可以循環(huán)創(chuàng)建對(duì)象或大的對(duì)象;
直到內(nèi)存不夠分配,產(chǎn)生棧溢出。
兩種情況:
• 線程請(qǐng)求的棧深度大于虛擬機(jī)允許的最大深度 StackOverflowError
• 虛擬機(jī)在擴(kuò)展棧深度時(shí),無法申請(qǐng)到足夠的內(nèi)存空間 OutOfMemoryError
創(chuàng)建對(duì)象時(shí)如果沒有可以分配的堆內(nèi)存,就會(huì)出現(xiàn)堆溢出。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class testCode {
public void testHeap(){//堆溢出
List<byte[]> list = new ArrayList<>();
int i=0;
while (true){
list.add(new byte[5*1024*1024]);
System.out.println("count is: "+(++i));
}
}
int num = 1;
public void testStack(){ //棧溢出
num++;
this.testStack();
}
public static void main(String[] agrs){
testCode t = new testCode();
t.testHeap();
t.testStack();
}
}
運(yùn)行結(jié)果:
//堆溢出:
count is: 343
count is: 344
count is: 345
count is: 346
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at testCode.testHeap(testCode.java:14)
at testCode.main(testCode.java:25)
//棧溢出:
StackOverflowError
• 1
• 2
另外,Java虛擬機(jī)的堆大小如何設(shè)置:命令行
java –Xms128m //JVM占用最小內(nèi)存
–Xmx512m //JVM占用最大內(nèi)存
–XX:PermSize=64m //最小堆大小
–XX:MaxPermSize=128m //最大堆大小
• 1
• 2
• 3
• 4
• 5
• 6