JVM內存模型和結構

JVM簡介:JVM 是可運行 Java 代碼的假想計算機 ,包括一套字節碼指令集、一組寄存器、一個棧、 一個垃圾回收,堆 和 一個存儲方法域。JVM 是運行在操作系統之上的,它與硬件沒有直接的交互。

JVM內存模型結構圖::: 

1.JVM內存模型和結構

   (1)JVM內存模型如下:::

                     Young(年輕代)=  New

                     Tenured(老年代)=  Old

                      Perm(永久代) = Perm

Young(年輕代)可以分爲Eden區和兩個Survivor區(from和to,這兩個Survivor區大小嚴格一致),新的對象實例總是首先放在Eden區,Survivor區作爲Eden區和 Tenure(終生代)的緩衝,可以向Tenure(終生代)轉移活動的對象實例。 

Tenure(終生代)中存放生命週期長久的實例對象,但並不是如它的名字那樣是終生的,裏面的對象照樣會被回收掉。

Young和Tenure共同組成了堆內存(默認新生代與老年代的空間大小爲1:2)。

Perm(永久代)則是非堆內存的組成部分。主要存放加載的Class類級對象如class本身,method,field等等

      JVM內存佈局規定了Java在運行過程中內存申請、分配、管理的策略,保證了JVM的高效穩定運行。

      在JVM啓動時,就已經保留了固定的內存空間給Heap內存,這部分內存並不一定都會被JVM使用,但是可以確定的是這部分保留的內存不會被其他進程使用。這部分內存大小由 -Xmx參數指定。而另一部分內存在JVM啓動時就分配給JVM,作爲JVM的初始Heap內存使用。影響這個的參數是 -Xms ,如果 -Xms 指定的值比-Xmx 的小,那麼兩者的差值就是Virtual內存值。隨着程序的運行,Eden區、 Tenured區和Perm區會逐漸使用保留的Virtual空間。堆內存默認值最大不會超過1G。

       絕大部分對象在Eden區生成,當Eden區裝填滿的時候,會觸發Young GC。垃圾回收的時候,在Eden區實現清除策略,沒有被引用的對象則直接回收,依然存活的對象會被移送到Survivor區。Survivor 區分爲S0和S1兩塊內存空間,送到哪塊空間呢?每次Young GC的時候,將存活的對象複製到未使用的那塊空間,然後將當前正在使用的空間完全清除,交換兩塊空間的使用狀態。如果Young GC要移送的對象大於Survivor區容量上限,則直接移交給老年代。每個對象都有一個計數器,每次YGC都會加1。參數能配置計數器能控制移交次數,默認值是15,意思就是在Survivor 區交換14次之後,晉升至老年代。Survivor 區處理超過上限,老年代也承受時,則會觸發Full Garbage Collection(Full GC);如果依然無法放下,則拋OutOfMemoryError,堆出現OOM的概率是所有內存耗盡異常中最高的。所以給JVM設置運行參數-XX:+HeapDumpOnOutOfMemoryError,讓JVM遇到OOM異常時能輸出堆內信息。

      整個Java虛擬機只有一個堆,所有的線程都訪問同一個堆。它是被所有線程共享的一塊內存區域,在虛擬機啓動時創建,而程序計數器、Java虛擬機棧、本地方法棧都是一個線程對應一個。堆是垃圾回收的主要區域,所以也被稱爲GC堆,堆的大小既可以固定也可以擴展,但主流的虛擬機堆的大小是可擴展的(通過-Xmx和-Xms控制),因此當線程請求分配內存,但堆已滿,且內存已滿無法再擴展時,就拋出OutOfMemoryError。

       所以開發工具(IDEA、Eclipse等)一般安裝完去修改內存,去提升性能。

             -Xms是設置java虛擬機的最小分配內存;-Xmx則是最大分配內存;512m爲內存空間

            一般-Xmx設置爲你電腦物理內存的1/4,而把-Xms和 -Xmx設置爲一樣,

            一般用到最多的就是 -Xms512m -Xmx512m

內存參數如圖:

  • -Xms設置堆的最小空間大小。
  • -Xmx設置堆的最大空間大小。
  • -XX:NewSize設置新生代最小空間大小。
  • -XX:MaxNewSize設置新生代最大空間大小。
  • -XX:PermSize設置永久代最小空間大小。
  • -XX:MaxPermSize設置永久代最大空間大小。
  • -Xss設置每個線程的堆棧大小
     

(2)JVM內存結構包含:堆、棧、方法區 

    堆:Heap堆是OutOfMemoryError(內存用完了:原因-內存泄漏或內存溢出)故障最主要的發源地,它存儲着幾乎所有的實例對象,堆由垃圾收集器自動回收,堆區由各子線程共享使用。通常情況下,它佔用的空間是所有內存區域中最大的,但如果無節制地創建大量對象,也容易消耗完所有的空間。堆的內存空間既可以固定大小,也可運行時動態地調整,通過如下參數設定初始值和最大值,比如-Xms512M. -Xmx512M。

           堆分成兩大塊:新生代和老年代
           對象產生之初在新生代,步入暮年時進入老年代,但是老年代也接納在新生代無法容納的超大對象

JVM運行機制圖:

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