每一個使用 Java 的開發者都知道 Java 字節碼是在 JRE 中運行。 JVM 則是 JRE 中的核心組成部分,承擔分析和執行 Java 字節碼的工做,而 Java 程序員一般並不須要深刻了解 JVM 運行狀況就能夠開發出大型應用和類庫。儘管如此,若是你對 JVM 有足夠了解,就會對 Java 有更好的掌握,而且能解決一些看起來簡單但又還沒有解決的問題。php
首先,咱們來看一下 JVM 不得不知道的體系結構,在編譯完以後的 class 文件裝載到類裝載器的運行時數據區,運行時數據區分爲五大塊,分別是方法區,堆, Java 棧,本地方法棧,程序計數器。Java棧,本地方法棧,程序計數器存儲本地方法接口,方法區和堆則存儲執行引擎,也是 GC 的做用區域。 程序員
JDK1.8以前,內存管理機制採用分代的策略:分爲新生代,老年代,永久代(JDK1.7及之前)。 面試
大體分爲 Eden 區和 Survivor 區, Survivor 區又分爲大小相同的兩部分: s0 ( FromSpace ) 和 s1 ( ToSpace )。新建的對象都是重新生代分配內存, Eden 區不足的時候,會把存活的對象轉移到 Survivor 區。當新生代進行垃圾回收時會觸發 Minor GC 。通常在Eden區分配對象,使用 TLAB( Thread Local Allocation Buffer ) 進行優化,在保存80%~90%生命週期較短的對象,GC頻率高,採用效率較高的複製算法。算法
新生代的三個分區默認比例爲 8:1:1 ,JVM中規定 98% 的對象要在新生代被回收,而 s0 及 s1 只是做爲暫存區,每次GC的觸發以後必須保證其中一個區是空的,隨後兩個區互換位置,及 s0 -> s1 (from -> to),s1 -> s0 (to -> from),保證絕大部分對象在此被回收。緩存
舊生代用於存放新生代屢次回收依然存活的對象,如緩存對象。當舊生代滿了的時候就須要對舊生代進行回收,舊生代的垃圾回收稱做 Major GC。新建的對象也有可能直接在舊生代中分配,取決於具體GC的實現。GC頻率相對較低,標記,清理,壓縮算法的各類結合和優化。架構
對象經歷了屢次 Major GC 仍然沒有被回收即進入永久代,僅 JDK1.7 及以前的版本擁有。學習
咱們首先來看一下哪些是GC的目標,GC中使用的回收檢測算法有兩種,目前虛擬機基本上都是用可達性算法:優化
每一個對象有一個引用計數器,當對象被引用一次則計數器加1,當對象引用失效一次則計數器減1,對於計數器爲0的對象意味着是垃圾對象,能夠被GC回收。 cdn
從GC Roots做爲起點開始搜索,那麼整個連通圖中的對象便都是活對象,對於GC Roots沒法到達的對象便成了垃圾回收的對象,隨時可被GC回收。 視頻
從根集合開始掃描,對存活的對象進行標記。
掃描整個內存空間,回收未被標記的對象,使用free-list記錄可回收區域。
與標記-清除同樣
再次掃描,並往一段滑動存活對象
有問題?能夠給我留言或私聊 有收穫?那就順手點個讚唄~
固然,也能夠到個人公衆號下「6曦軒」,
回覆「學習」,便可收到一份 【Java工程師進階架構師的視頻教程】~
回覆「面試」,能夠收到一套 【本人嘔心瀝血整理的Java面試題目】(部分目錄以下)
因爲我咧,科班出身的程序員,php,Android以及硬件方面都作過,不過最後仍是選擇專一於作 Java,因此有啥問題能夠到公衆號提問討論(技術情感傾訴均可以哈哈哈),看到的話會盡快回復,但願能夠跟你們共同窗習進步,關於服務端架構,Java 核心知識解析,職業生涯,面試總結等文章會不按期堅持推送輸出,歡迎你們關注~~~