JVM內存管理及垃圾回收

轉載出處:(http://blog.csdn.net/zhangerqing程序員

Java虛擬機會將內存分爲幾個不一樣的管理區,這些區域各自有各自的用途,根據不一樣的特色,承擔不一樣的任務以及在垃圾回收時運用不一樣的算法。整體分爲下面幾個部分:算法

程序計數器(Program Counter Register)、JVM虛擬機棧(JVM Stacks)、本地方法棧(Native Method Stacks)、堆(Heap)、方法區(Method Area)數組

 

一、程序計數器(Program Counter Register)多線程

這是一塊比較小的內存,不在Ram上,而是直接劃分在CPU上的,程序員沒法直接操做它,它的做用是:JVM在解釋字節碼文件(.class)時,存儲當前線程所執行的字節碼的行號,只是一種概念模型,各類JVM所採用的方式不一樣,字節碼解釋器工做時,就是經過改變程序計數器的值來選取下一條要執行的指令,分支、循環、跳轉、等基礎功能都是依賴此技術區完成的。還有一種狀況,就是咱們常說的Java多線程方面的,多線程就是經過現程輪流切換而達到的,同一時刻,一個內核只能執行一個指令,因此,對於每個程序來講,必須有一個計數器來記錄程序的執行進度,這樣,當現程恢復執行的時候,才能從正確的地方開始,因此,每一個線程都必須有一個獨立的程序計數器,這類計數器爲線程私有的內存。若是一個線程正在執行一個Java方法,則計數器記錄的是字節碼的指令的地址,若是執行的一個Native方法,則計數器的記錄爲空,此內存區是惟一一個在Java規範中沒有任何OutOfMemoryError狀況的區域。函數

二、JVM虛擬機棧(JVM Stacks)性能

JVM虛擬機棧就是咱們常說的堆棧的棧(咱們經常把內存粗略分爲堆和棧),和程序計數器同樣,也是線程私有的,生命週期和線程同樣,每一個方法被執行的時候會產生一個棧幀,用於存儲局部變量表、動態連接、操做數、方法出口等信息。方法的執行過程就是棧幀在JVM中出棧和入棧的過程。局部變量表中存放的是各類基本數據類型,如boolean、byte、char、等8種,及引用類型(存放的是指向各個對象的內存地址),所以,它有一個特色:內存空間能夠在編譯期間就肯定,運行期不在改變。這個內存區域會有兩種可能的Java異常:StackOverFlowError和OutOfMemoryError。優化

三、本地方法棧(Native Method Stacks)操作系統

從名字便可看出,本地方法棧就是用來處理Java中的本地方法的,Java類的祖先類Object中有衆多Native方法,如hashCode()、wait()等,他們的執行不少時候是藉助於操做系統,可是JVM須要對他們作一些規範,來處理他們的執行過程。此區域,能夠有不一樣的實現方法,向咱們經常使用的Sun的JVM就是本地方法棧和JVM虛擬機棧是同一個。.net

四、堆(Heap)線程

堆內存是內存中最重要的一塊,也是最有必要進行深究的一部分。由於Java性能的優化,主要就是針對這部份內存的。全部的對象實例及數組都是在堆上面分配的(隨着JIT技術的逐漸成熟,這句話視乎有些絕對,不過至少目前還基本是這樣的),可經過-Xmx和-Xms來控制堆的大小。JIT技術的發展產生了新的技術,如棧上分配和標量替換,也許在不久的幾年裏,即時編譯會誕生及成熟,那個時候,「全部的對象實例及數組都是在堆上面分配的」這句話就應該稍微改改了。堆內存是垃圾回收的主要區域,因此在下文垃圾回收板塊會重點介紹,此處只作概念方面的解釋。在32位系統上最大爲2G,64位系統上無限制。可經過-Xms和-Xmx控制,-Xms爲JVM啓動時申請的最小Heap內存,-Xmx爲JVM可申請的最大Heap內存。

五、方法區(Method Area)

 方法區是全部線程共享的內存區域,用於存儲已經被JVM加載的類信息、常量、靜態變量等數據,通常來講,方法區屬於持久代(關於持久代,會在GC部分詳細介紹,除了持久代,還有新生代和舊生代),也難怪Java規範將方法區描述爲堆的一個邏輯部分,可是它不是堆。方法區的垃圾回收比較棘手,就算是Sun的HotSpot VM在這方面也沒有作得多麼完美。此處引入方法區中一個重要的概念:運行時常量池。主要用於存放在編譯過程當中產生的字面量(字面量簡單理解就是常量)和引用。通常狀況,常量的內存分配在編譯期間就能肯定,但不必定全是,有一些可能就是運行時也可將常量放入常量池中,如String類中有個Native方法intern()<關於intern()的詳細說明,請看另外一篇文章:http://blog.csdn.net/zhangerqing/article/details/8093919>

此處補充一個在JVM內存管理以外的一個內存區:直接內存。在JDK1.4中新加入類NIO類,引入了一種基於通道與緩衝區的I/O方式,它可使用Native函數庫直接分配堆外內存,即咱們所說的直接內存,這樣在某些場景中會提升程序的性能。

相關文章
相關標籤/搜索