1. 程式人生 > >java虛擬機之常見的報錯

java虛擬機之常見的報錯

溢出 system 虛擬機棧 系統 大於 xss tst 產生 art

1、最簡單的內存溢出

public class HeapOOM {
    HeapOOM[] testlist= new HeapOOM[100000];
    public static void main(String[] args) {
        List<HeapOOM> list= new ArrayList<HeapOOM>();
        while(true){
            list.add(new HeapOOM());
        }
    }
}

  

2、虛擬機棧和本地方法棧溢出(-Xss:棧內存容量)

  兩種異常:

    如果線程請求的深度大於虛擬機所允許的最大深度,將拋出StackOverflowError異常。

    如果虛擬機在擴展棧時無法申請到足夠的內存空間,則拋出OutOfMemoryError異常。

  單線程時棧溢出:

public class StackOverflow {
    private int stackLength = 1;
    public void stackLeak(){
        stackLength++;
        stackLeak();
    }

    public static void main(String[] args) throws Throwable {
        StackOverflow stackOverflowError = new StackOverflow();
        try {
            stackOverflowError.stackLeak();
        }catch (Throwable e){
            System.out.println("stack 深度:"+stackOverflowError.stackLength);
            throw e;
        }

    }
}

  多線程下的棧溢出:

    通過不斷建立線程的方式可以產生內存溢出異常。在這種情況下,為每個線程的棧分配的內存越大,越容易產生內存溢出異常。

原因是:操作系統分配給每個進程的內存是有限制的,譬如32位的Windows限制為2GB。虛擬機提供了參數來控制Java堆和方法區的兩部分內存的最大值。剩余的內存為2GB減去Xmx(最大堆容量),再減去MaxPermSize(最大方法區容量)

public class StackOverThread {
    private void donnotStop(){
        while (true){
            donnotStop();
        }
    }
    public void stackLeakByThread(){
        while (true){
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    donnotStop();
                }
            });
            thread.start();
        }

    }
    public static void main(String[] args) {
        StackOverThread stackOverThread = new StackOverThread();
        stackOverThread.stackLeakByThread();
    }
}

  

3、

  

java虛擬機之常見的報錯