首頁 > Java > java教程 > 主體

分享一個Java記憶體分佈的歸納整理

Y2J
發布: 2017-04-28 10:09:46
原創
1522 人瀏覽過

這篇文章主要介紹了java程式運行時記憶體分佈詳解,需要的朋友可以參考下

Java記憶體分佈:Java虛擬機在執行Java程式的過程中會把它所管理的記憶體分割成若干不同的資料區:方法區、虛擬機器堆疊、本機方法堆疊、堆疊、程式計數器。

1.程式計數器

程式計數器是一塊較小的記憶體空間,它可以看做是目前執行緒所執行的字節碼的行號指示器。在虛擬機器的概念模型中,字節碼解釋器工作時就是透過改變這個計數器的值來選取嚇一個需要執行的字節碼指令。

分支、循環、跳躍、異常處理、執行緒復原等基礎功能都需要依賴這個計數器來完成。

為了線程切換後能恢復到正確的執行位置,每條線程都需要有一個獨立的程式計數器,各條線程之間計數器互不影響,獨立存儲,所以該類內存區域為“線程私有“ 的記憶體。

如果執行緒正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機器字節碼指令的位址;如果正在執行的是Native方法,這個計數器值則為空,此記憶體區域是唯一一個子啊Java虛擬機器規格中沒有規定任何OutOfMemoryError情況的區域。

2.Java虛擬機器堆疊

與程式計數器一樣,Java虛擬機器堆疊也是執行緒私有的,它的生命週期和執行緒相同。虛擬機器棧描述的是Java方法執行的記憶體模型;每個方法在執行的同時都會建立一個堆疊幀用於儲存局部變數表、操作數棧、動態連結、方法出口等資訊。

每一個方法從呼叫到執行完成,都對應一個堆疊幀在虛擬機器堆疊中入棧到出棧的過程。

局部變數表存放了編譯期可知的各種基本資料型別、物件參考(不等同於對象,是指向對象的參考)和returnAddress類型。如果執行緒請求的堆疊深度大於虛擬機器所允許的深度,將會拋出StackOverflowError異常,如果無法申請到足夠的記憶體會拋出OutOfMemory例外。

3.本機方法堆疊

本機方法堆疊與虛擬機器堆疊之間的差異是虛擬機器堆疊為虛擬機器執行的Java(字節碼)服務,而本地方法堆疊則為虛擬機器使用到的Native方法服務。

4.Java堆

Java堆是所有執行緒共享的記憶體區域,在虛擬機器啟動時創建。此記憶體區域的唯一目的是存放物件實例,Java堆是垃圾回收器管理的主要區域

5.方法區

方法區和Java堆一樣,是各個執行緒共享的記憶體區域,用於儲存已被虛擬機器載入的類別資訊、常數、靜態變數、即時編譯器編譯後的程式碼等資料。

6.運行時常數池

運行時常數池是方法區的一部份。 Class檔案中除了有類別的版本、欄位、方法、介面等描述資訊外,還有一項資訊是常數池,用於存放編譯期產生的各種字面量和符號引用,這部分內容將會在類別中載入後進入方法區的運轉時常量池中存放。

網路上很多解釋常數池會以字串為例:

#例如

String s1 = "Hello";
String s2 = "Hello";
String s3 = "Hel" + "lo";
String s4 = "Hel" + new String("lo");
String s5 = new String("Hello");
String s6 = s5.intern();
String s7 = "H";
String s8 = "ello";
String s9 = s7 + s8;
 
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // true
System.out.println(s1 == s4); // false
System.out.println(s1 == s9); // false
System.out.println(s4 == s5); // false
System.out.println(s1 == s6); // true
登入後複製

s1==s2為true很好理解,指向同一個常量池的記憶體位址。

s1==s3為true:對於s3而言,由於拼接的都是字面量,那麼編譯器會被最佳化,其實就是指s3="Hello"

#s1== s4為false:由於new String("lo")並不是一個字面量,而是一個變量,這樣的話編譯器不會被最佳化,因為該變數可能會改變。

s1==s9為false:和上面一樣的道理。

s4==s5:兩個不同物件的引用當然不同。

s1==s6:由於String.intern()方法是指:如果常數池已經包含一個等於此String 物件的字串(該物件由 equals(Object ) 方法確定),則傳回池中的字串。否則,將此 String 物件新增至池中,並且傳回此 String 物件的參考。 它遵循對任何兩個字串 s 和 t,當且僅當 s.equals(t) 為 true 時,s.intern() == t.intern() 才為 true。

以上是分享一個Java記憶體分佈的歸納整理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板