1、記憶體模型
JVM 把記憶體分為了5個大的區域
程式計數器
線程私有 很小的一塊區域存放目前正在執行的位元組碼指令唯一一塊不會抛出任何異常的區域
程式計數器
線程私有 很小的一塊區域存放目前正在執行的位元組碼指令唯一一塊不會抛出任何異常的區域
java虛拟機棧
線程私有 會抛出OOM異常和 StackOverflowError存儲了方法執行時相關資訊(棧幀)
本地方法棧
線程私有會抛出OOM異常和 StackOverflowError存儲本地方法(也就是native修飾的函數)調用相關資訊和java虛拟機棧統稱棧
方法區
線程共有 會有并發問題會抛出OOM異常存儲的是每個class的資訊包括,類名,屬性名,函數名等函數的代碼,和 運作時常量池
堆
線程共有并發問題主要發生在這裡最大的一塊記憶體區域,這一個區域又被分為了幾個小的區域年輕代:老年代,大小比例預設為 1:2新new出來的對象基本都在年輕代(大對象會直接進入老年代),新生代的對象大部分都是朝生夕死,經過多倫(預設15)moinergc依然存貨的對象會進入老年代年輕代GC一般采用标記複制算法,存活的對象都複制到 survivor區域。老年代的對象存活率比較高,這裡發生的GC叫FullGC一般采用CMS算法(标記整理算法)或者G1算法(jdk1.9後預設的)
jvm 标記一個對象是否是垃圾的方法:
1、引用計數法 – 無法解決循環引用問題
2、對象可達性分析 – 從根對象搜尋,無法到達的對象未垃圾對象,需要被回收 – 三色标記法就是該算法的實踐
垃圾回收
年輕代 – 标記複制算法
年輕代按照 8(eden):1(survivor0):1(survivor1) 被分為三塊區域
初始狀态 survivor 2個區域都為空,經過第一輪GC後會吧 存活對象複制進 survivor0 區域,在清空 eden 區域,當 survivor0 區域滿了後會複制進 survivor1 區域survivor1 區域滿了後會進入 老年代,并且 survivor0 和 survivor1 會始終保持一個區域為空,
老年代 – 标記整理算法(CMS 算法)
會分為幾個步驟
1、初始标記
2、并發标記
3、重新标記
4、并發處理
對象在标記過程中,根據标記情況,分成三類:
白色對象,表示自身未被标記;
灰色對象,表示自身被标記,但内部引用未被處理;
黑色對象,表示自身被标記,内部引用都被處理;
更多 JAVA 相關問題關注小程式,如果對你有用幫忙點下廣告,謝謝!!