(1)方法區(一般稱永久代)
1、所有線程共享的區域
2、主要存放類信息、常量、靜態變量、常量池等
(2)虛擬機棧
1、線程私有的內存區域
2、每個方法調用都會創建自己的棧幀,都屬於該虛擬機棧
3、棧幀中的局部變量表內存大小在編譯期就完成確定,方法運行期間大小不會改變
(3)本地方法棧
1、不同虛擬機有不同的實現、線程私有
(4)堆(一般稱新生代)
1、所有線程共享的區域,所佔空間最大,用於存放對象實例
(5)程序計數器
1、可看作是字節碼的行號指示器,每個線程都會有自己的程序計數器且互不影響,所以是線程私有的內存區域,空間較小
2、當執行native方法時,計數器值爲空
3、此區域是唯一一個不會出現OutOfMemoryError情況的內存區域
二、判斷對象已死算法
(1)引用計數
1、Java語言未採用該算法,它不能解決循環引用或相互引用的問題
(2)根搜索算法
1、Java和C#都採用這種算法,原理就是作用域搜索,從根開始搜索對象不可達即可回收
三、垃圾回收算法
(1)標記清除算法(可用於老年代)
缺點:效率不高、會產生大量內存碎片
(2)複製算法(主要用於新生代)
原理:將內存分爲兩塊,每次只用一塊。用完將活着的對象進行復制
HotSpot虛擬機實現:內存分爲三塊,一塊較大的Eden區和兩塊較小的Survivor區; 且Eden : Survivor : Survivor = 8:1:1
分配擔保策略:如果垃圾回收後存活的對象在另一塊Survivor區存不下,將直接在老年代中申請內存
(3)標記整理(標記壓縮)算法(可用於老年代)
原理:所有存活對象向一端移動,清理邊界外的內存
(4)分代收集算法(一般和其他算法結合使用)
四、垃圾收集器
(1)Serial收集器(新生代)
單線程、工作時會暫停工作線程、簡單高效、Client模式的最佳選擇
(2)ParNew收集器(新生代)
Serial收集器的多線程版本、Server模式的最佳選擇
(3)Parallel Scavenge收集器(新生代)
採用了複製算法、多線程、吞吐量優先
(4)Serial Old收集器(老年代)
單線程、使用標記整理算法、Client模式
(5)Parallel Old收集器(老年代)
多線程、使用標記整理算法
(6)CMS收集器(老年代)
基於標記清除算法
(7)G1收集器(最新)
基於標記整理算法
五、常見虛擬機參數
(1)SurvivorRatio
新生代中Eden區域和Survivor區域容量的比值,默認爲8
(2)PretenureSizeThreshold 或 MaxTenuringThreshold
直接晉升到老年代的年齡,大於這個參數直接在老年代分配內存(默認15)
(3)PermSize、MaxPermSize
永久代初始值、永久代的最大值(默認64M)
(4)-Xms、-Xmx
初始堆大小、最大堆大小
(5)NewRatio
永久代和新生代的比值
(6)-Xmn 或 NewSize
新生代大小
(7)GCTimeRatio
吞吐量,默認值99,1/(1+99)=1%,即允許1%的GC時間
(8)MaxNewSize
最大新生代大小
(9)TargetSurvivorRatio
survivor區的可使用率,當該區空間利用率達到該值時,會將對象放到老年代