Java JVM:內存結構和相關參數

包括:

一. Java 整體內存結構

二. Java 堆內存結構

三. Java 堆內存和非堆內存參數


一. Java 整體內存結構

以下針對JDK7:

圖1

如圖1,JVM內存區域分爲PC寄存器,JVM方法棧,本地方法棧,JVM方法區,JVM堆。

  • PC寄存器:存放下一條指令在方法中的偏移量。也可以看做是線程所執行的字節碼的行號指示器,字節碼解釋器的工作就是通過改變這個計數器的值來選取下一條需要執行的指令。
  • JVM方法棧:PC寄存器,JVM方法棧,和本地方法棧都是線程私有。在JVM方法棧有,有局部變量區和操作數區。人們經常說的JVM內存分爲堆內存和棧內存(這 是一個比較籠統的說法)中的棧內存也就是指這個JVM方法棧的內存。當線程請求的棧的深度大於虛擬機所允許的深度時,就會拋出StackOverFlow 異常;如果虛擬機棧可以動態擴展,當擴展的時候無法申請足夠的內存,會拋出OutOfMemory異常。
  • 本地方法棧:主要用來支持native方法,記錄native方法調用的狀態。可以把native 方法看成是 java 調用 非 java 代碼的一個接口。主要用於允許Java 和其他語言,比如 C 語言進行交互。
  • JVM方法區:主要存儲已經加載的類的信息,比如構造函數的信息,方法的信息,常量的信息。Class對象提供的getXXX()方法取得的類的信息就是從JVM方法區中得到。Ps:JVM方法區是永久代的一個子集,常量池也是放在JVM方法區中。
  • JVM堆:主要目的是用來存放數組和對象。同時,JVM 堆也是 內存溢出垃圾回收的主要區域。
二. Java 堆內存結構


圖2


如圖2所示,在JVM堆中,又分爲新生代,老生代

        可以看到,新生代中,又分爲eden區域和兩個Survivor區域。(由於回收機制採用複製算法,所以這樣分,可看另一篇垃圾收集博文)默認比例爲8:1:1,也就是說,可以用的內存爲90%(另一篇垃圾收集博文說有爲什麼),當然,可以用-XX:SurvivorRatio設置eden和Survivor的比值,默認爲8:1。

        特別注意:最右側的永久代在JDK8中已經不在存在,被元空間代替metaspace所代替。另外,在jdk7中,字符串內部池就已經從永久代中移除。



三. Java 堆內存和非堆內存參數

  •  -XX:Persize:設置非堆內存初始值,默認爲1/64。
  • -XX:MaxPersize:設置非堆內存最大值,默認爲1/4.
  • -Xss:設置每個線程佔用堆內存大小,現在默認爲1M,以前爲256K。設置線程越小,堆內存大小不變,可以創造的線程數越多(當然有一個限度)。但是這個值也需要經過嚴格的測試再設置。
  • -Xms:JVM堆初始分配內存。默認爲物理內存的1/64,當默認堆內存的空餘空間小於40%的時候,這個堆內存就會自動增長到-Xmx指定的最大堆分配內存。
  • -Xmx :JVM的最大堆分配內存。默認爲物理內存的1/4,當空餘內存大於70%的時候,該堆內存又會自動減少到-Xms指定的內存。
  • -Xmn:指定新生代的內存大小。當堆大小不變的情況下,新生代越大,老生代越小,默認新生代和老年代的比例爲1:2,而且這個比例會嚴重影響系統性能,sun推薦爲新生代佔整個堆內存3/8。
  • -XX:SurvivorRatio:新生代中,又分爲eden區域和兩個Survivor區域。默認比例爲8:1:1,也就是說,可以用的內存爲90%。該參數用來設置eden和Survivor的比值,默認爲8:1。




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