筆記_Java內存分配

《Java內存分配》

 

Java內存分配和管理是Java的核心技術之一。涉及以下:棧、堆、常量池、靜態域。

  1.  常量池:constant pool。指在編譯期被確定,並被保存在已編譯的.class文件中的一些數據。是個有序集合,以表的形式。主要包括:

    a) 用final定義的常量。可以是基本數據類型(int、long等),是對象型(數組等)。

b) 類、接口、字段、方法的名字和描述符。

注意的是,String作爲特殊的類型,若初始化方式是String a = "abc",則"abc"是存於常量池中的,即String字符串是不可變的。而String a = new String("abc")則不同。

  2.  靜態域:存放在隊形中用static定義的成員。

  3.  棧:使用上特點是讀取速度快,但是隻能存定長的、不可變的數據。

    當在一段代碼塊定義一個變量時,Java就在棧中爲這個變量分配內存空間;當該變量退出該作用域後,Java會自動釋放掉爲該變量所分配的內存空間,該內存空間立即被另作他用。主要包括:

a) 基本數據類型的變量及其數據

    eg:int a = 9。a和9都存在棧中,並且a指向9。注意,當同時有int b = 9時,則只存入b並指向9;當a的值改變,如下面有a = 10,則存入10並讓a指向10。基本數據變量的這種儲存方式,與引用變量完全不同。

 b) 引用數據類型(即,對象)的引用變量。

     引用變量是一個內存地址(Java指針),指向該對象在堆中儲存的數據的首地址。

  4.  堆:用來存放new出來的對象和數組。

    引用變量在程序運行到其該作用域之外時,Java會自動釋放掉棧中的引用變量;注意,堆中的數據不會立即被釋放;在堆中分配的內存,由GC(JVM垃圾自動回收器)來不定期回收。

   5. String的存儲方式:String包裝類比較特殊,跟基本數據類型和對象的存儲方式都不同,而且初始化方式、+連接運算符等會有特殊的處理方式。

初始化時,其引用存於,但是數據可能存放在常量池中(編譯時就已創建好),有的存放在堆中(運行時才被創建)。

eg:String a = "hello";

String b = "hello";

System.out.println(a == b);   //true

上例,這種初始化方式,"hello"存放於常量池中,a和b都指向它。

eg:String a = new String("hello");

String b = new String ("hello");

System.out.println(a == b);   //false

System.out.println(a.equals(b));   //true

上例,兩次初始化new了兩個對象,堆中沒有常量池或棧的那種機制,不會判斷兩次new的對象的數據是否相等,所以是false。

注意:a.equals(b)取決於是否重寫了equals方法,Object類的默認equals()方法比較的就是a == b;String重寫了equals方法。

 

    6. 值傳遞和引用傳遞:跟上述內存分配機制密切相關,總結爲:

a. 值傳遞(傳遞的是拷貝):基本數據類型 和 String的直接複製情況。(即常量池)

b. 引用傳遞(傳遞的是引用&指針&內存地址):引用數據類型。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章