JVM學習筆記——自動內存管理

堆、棧、程序計數器
程序計數器:線程私有,程序計數器是爲一個沒有OOM錯誤的區域
棧:線程私有,線程所請求的棧深度大於虛擬機容許的深度,會拋出StackOverflowError異常;虛擬機沒有足夠的內存擴展時,會拋出OutOfMemoryError異常。
堆:線程共享,用於存放對象實例,GC做用與此,堆沒有足夠的內存擴展時,會拋出OutOfMemoryError異常。java

Xss:JVM中的棧容量
Xms:JVM中的堆初始化容量
Xmx:JVM中的堆最大容量
Xmn:JVM中年輕代的容量
java -Xmx2048m -Xms256m,JVM以256M的堆內存啓動,當堆內存不夠時,擴展內存,最大可達2048M算法

JVM有許多不一樣的實現,其中HotSpot爲Oracle的Java SE的主要實現。線程

新生代進入老年代

預約年齡

若是新生代經歷一次GC沒有被清理掉的話,那麼它的年齡就加1歲,當到必定歲數(默認15歲)後,就能夠進入老年代。3d

動態年齡

若是在Survivor空間中,全部相同年齡的對象所佔空間達到Survivor空間的一半,那麼以該年齡爲閾值,大於等於該年齡的對象進入老年代。code

對象存活分析

引用計數法

給對象添加一個引用計數器,每當有一個地方引用了該對象,引用數就加1;引用失效,引用數就減1。
引用計數法有一個缺點:循環引用的「孤島」沒法被GC。
主流的java虛擬機不使用該方法判斷對象的死活。對象

可達性分析法

以「根節點」爲出發點,能夠將其餘對象都串起來,構成一個引用鏈。若某個對象不在該引用鏈上,就被判斷已死。
可做爲「根結點」的有:1.棧中引用的對象;2.方法區中類靜態屬性引用的對象;3.方法區中常量引用的對象;4.本地方法棧中JNI引用的對象。
主流的java虛擬機使用可達性分析法判斷對象的死活。blog

垃圾收集算法

對於已死的對象,咱們應該對其進行垃圾收集。內存

標記-清除


該算法的最大缺點是標記清除後,會產生許多內存碎片。虛擬機

複製


將內存劃爲多個區域,一次只用一個,啓動垃圾收集的時候,將存活的對象都複製到新的內存塊中,這樣它們都是整齊的。
上圖的1:1比例比較浪費內存空間。在實現中,通常是將內存分爲1塊較大的Eden空間和2塊較小的Survivor空間(Eden空間:Survivor空間默認爲8:1)。每次使用Eden和一塊Survivor,另一塊Survivor空着。當啓動垃圾收集時,將那兩塊中的存活對象複製到空着的Survivor塊。若是空着的Survivor塊放不下存活對象的話,會存放到老年代的內存中。
大多數JVM採用複製算法對新生代進行垃圾收集。擴展

標記-整理

標記-整理算法結合了前二者,適用於老年代的垃圾收集。

相關文章
相關標籤/搜索