1. 程式人生 > >寫Java程式碼分別使堆溢位,棧溢位

寫Java程式碼分別使堆溢位,棧溢位

原文連結:https://www.cnblogs.com/tv151579/p/3647238.html

轉自:http://fxlzs2000.iteye.com/blog/1786407

轉自:http://my.oschina.net/sdrkyj/blog/143410

前言

primitive type: 基本型別,像int、double就是。
wrapped type:包裝型別,int—>Integer,double—>Decimal

基本型別跟就是不可例項化的,可以直接初始化、賦值、運算。不可呼叫方法,不可放入容器(要求必須是類例項才行)。
包裝型別就是把基本型別變成一個類例項,一定要new才產生,可以呼叫方法,可以放入容器。

首先要搞清楚堆疊裡放的什麼東西:

棧儲存執行時宣告的變數——物件引用(或基礎型別, primitive)記憶體空間,堆分配每一個物件內容(例項)記憶體空間。

一個變數可以先後指向多個物件例項;陣列、連結串列等可以存放對多個例項物件內容的引用關係。沒有引用關係的物件內容按說被虛擬機器回收(recycled,destroy,在C++叫delete,在C叫free)。 棧的實現是先入後出的, 相似的集裝箱那種貨艙。 堆是隨機存放的, 相似於現在的停車場。 記得曾經,有一本遊戲的外國書, 說遊戲要分配好棧空間和堆空間; 在開始時候分配固定容量的空間, 有不同的自頂向下和從下向上的地址空間分配。

stackoverflow , 總是在無限遞迴呼叫時候可以看見(google也經常有同名網站的結果)。

堆記憶體滿, 可以通過無限new實現。

======================華麗的分隔符================================

在JAVA中,可以使用關鍵字new來建立Java物件。例如,

ArrayList list = new ArrayList();

實際上,在建立完上面的一個物件後,在JVM中,會把new出來的物件存放在堆記憶體中,

同時,在方法棧中存放著物件的引用關係。

如果想要堆溢位,比較簡單,可以迴圈建立物件或大的物件;

如果想要棧溢位,可以遞迴呼叫方法,這樣隨著棧深度的增加,JVM 維持著一條長長的方法呼叫軌跡,

直到記憶體不夠分配,產生棧溢位。

因此,可以使用下面簡單的程式碼實現堆溢位和棧溢位。

複製程式碼
public class Test {

    public void testHeap(){
        for(;;){
              ArrayList list = new ArrayList (2000);
          }
    }
    int num=1;
    public void testStack(){
        num++;
        this.testStack();
     }
    
    public static void main(String[] args){
        Test  t  = new Test ();
        t.testHeap();
        t.testStack();   
    }
}
複製程式碼

另外,Java虛擬機器的堆大小如何設定:命令列

 java –Xms128m //JVM佔用最小記憶體

           –Xmx512m //JVM佔用最大記憶體

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

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