史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

前言

作為 Java 的從業者,在找工作的時候,一定會被問及關於 JVM 相關的知識。 JVM 知識的掌握程度,在很多面試官眼裡是候選人技術深度的一個重要評判標準。而大多數人可能沒有對 JVM 的實際開發和使用經驗,接下來這一系列文章將帶你深入瞭解 JVM 需要掌握的各個知識點。這也將幫助你完成從初級程序員到高級程序員的轉變。

由於文章篇幅原因,文末有答案和解析

目錄

  • 線程(詳解)
  • JVM內存區域(詳解)
  • JVM運行時內存
  • 垃圾回收與算法
  • JAVA四種引用類型
  • GC分代收集算法VS分區收集算法
  • GC垃圾收集器
  • JAVA IO/NIO
  • JVM類加載機制
  • 正文

    一、線程(詳解)

    這裡所說的線程指程序執行過程中的一個線程實體。JVM 允許一個應用併發執行多個線程。Hotspot JVM 中的 Java 線程與原生操作系統線程有直接的映射關係。當線程本地存儲、緩衝區分配、同步對象、棧、程序計數器等準備好以後,就會創建一個操作系統原生線程。Java 線程結束,原生線程隨之被回收。操作系統負責調度所有線程,並把它們分配到任何可用的 CPU 上。當原生線程初始化完畢,就會調用 Java 線程的 run() 方法。當線程結束時,會釋放原生線程和 Java 線程的所有資源。

    Hotspot JVM 後臺運行的系統線程主要有下面幾個:

    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    二、JVM內存區域(詳解)

    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    JVM 內存區域主要分為線程私有區域【程序計數器、虛擬機棧、本地方法區】、線程共享區域【JAVA 堆、方法區】、直接內存。

    線程私有數據區域生命週期與線程相同, 依賴用戶線程的啟動/結束 而 創建/銷燬(在 HotspotVM 內, 每個線程都與操作系統的本地線程直接映射, 因此這部分內存區域的存/否跟隨本地線程的生/死對應)。

    線程共享區域隨虛擬機的啟動/關閉而創建/銷燬。

    直接內存並不是 JVM 運行時數據區的一部分, 但也會被頻繁的使用: 在 JDK 1.4 引入的 NIO 提供了基於 Channel 與 Buffer 的 IO 方式, 它可以使用 Native 函數庫直接分配堆外內存, 然後使用DirectByteBuffer 對象作為這塊內存的引用進行操作(詳見: Java I/O 擴展), 這樣就避免了在 Java堆和 Native 堆中來回複製數據, 因此在一些場景中可以顯著提高性能。

    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    1、程序計數器( 線程私有)

    • 一塊較小的內存空間, 是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱為“線程私有”的內存。
    • 正在執行 java 方法的話,計數器記錄的是虛擬機字節碼指令的地址(當前指令的地址)。如果還是 Native 方法,則為空。
    • 這個內存區域是唯一一個在虛擬機中沒有規定任何 OutOfMemoryError 情況的區域。

    2、虛擬機棧( 線程私有)

    是描述java方法執行的內存模型,每個方法在執行的同時都會創建一個棧幀(Stack Frame)用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中入棧到出棧的過程。

    棧幀( Frame)是用來存儲數據和部分過程結果的數據結構,同時也被用來處理動態鏈接(Dynamic Linking)、 方法返回值和異常分派( Dispatch Exception)。棧幀隨著方法調用而創建,隨著方法結束而銷燬——無論方法是正常完成還是異常完成(拋出了在方法內未被捕獲的異常)都算作方法結束。

    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    3、本地方法區(線程私有)

    本地方法區和 Java Stack 作用類似, 區別是虛擬機棧為執行 Java 方法服務, 而本地方法棧則為Native 方法服務, 如果一個 VM 實現使用 C-linkage 模型來支持 Native 調用, 那麼該棧將會是一個C 棧,但 HotSpot VM 直接就把本地方法棧和虛擬機棧合二為一。

    4、堆(Heap- 線程共享)-運行時數據區

    是被線程共享的一塊內存區域,創建的對象和數組都保存在 Java 堆內存中,也是垃圾收集器進行垃圾收集的最重要的內存區域。由於現代 VM 採用分代收集算法, 因此 Java 堆從 GC 的角度還可以細分為: 新生代( Eden 區 、 From Survivor 區 和 To Survivor 區 )和老年代。

    5、方法區/ 永久代(線程共享)

    即我們常說的永久代(Permanent Generation), 用於存儲被 JVM 加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據. HotSpot VM把GC分代收集擴展至方法區, 即使用Java堆的永久代來實現方法區, 這樣 HotSpot 的垃圾收集器就可以像管理 Java 堆一樣管理這部分內存,而不必為方法區開發專門的內存管理器(永久帶的內存回收的主要目標是針對常量池的回收和類型的卸載, 因此收益一般很小)。

    運行時常量池(Runtime Constant Pool)是方法區的一部分。Class 文件中除了有類的版本、字段、方法、接口等描述等信息外,還有一項信息是常量池Constant Pool Table),用於存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載後存放到方法區的運行時常量池中。 Java 虛擬機對 Class 文件的每一部分(自然也包括常量池)的格式都有嚴格的規定,每一個字節用於存儲哪種數據都必須符合規範上的要求,這樣才會被虛擬機認可、裝載和執行。

    更多解析:

    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    三、JVM運行時內存

    • 新生代
    • 老年代
    • 永久代
    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    四、垃圾回收與算法

    • 如何確定垃圾
    • 標記清除算法( Mark-Sweep )
    • 複製算法(copying)
    • 標記整理算法(Mark-Compact)
    • 分代收集算法
    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    五、JAVA 四中引用類型

    • 強引用
    • 軟引用
    • 弱應用
    • 虛引用
    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    六、GC分代收集算法VS分區收集算法

    • 分代收集算法
    • 分區收集算法
    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    七、GC垃圾收集器

    文章資料都整理在一個文檔裡面了,需要的朋友可以私信"JVM”獲取喲

    • Serial 垃圾收集器 (單線程、 複製算法)
    • ParNew 垃圾收集器 (Serial+ 多線程)
    • Parallel Scavenge 收集器(多線程複製算法、高效)
    • Serial Old 收集器 (單線程標記整理算法 )
    • Parallel Old 收集器(多線程標記整理算法)
    • CMS 收集器(多線程標記清除算法)
    • G1 收集器(解析)

    G1 收集器(解析)

    Garbage first 垃圾收集器是目前垃圾收集器理論發展的最前沿成果,相比與 CMS 收集器,G1 收集器兩個最突出的改進是:

    1. 基於標記-整理算法,不產生內存碎片。

    2. 可以非常精確控制停頓時間,在不犧牲吞吐量前提下,實現低停頓垃圾回收。

    G1 收集器避免全區域垃圾收集,它把堆內存劃分為大小固定的幾個獨立區域,並且跟蹤這些區域的垃圾收集進度,同時在後臺維護一個優先級列表,每次根據所允許的收集時間,優先回收垃圾最多的區域。區域劃分和優先級區域回收機制,確保 G1 收集器可以在有限時間獲得最高的垃圾收集效率。

    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    八、JAVA IO/NIO

    • 阻塞 IO模型
    • 非阻塞 IO模型
    • 多路複用 IO模型
    • 信號驅動 IO模型
    • 異步 IO模型
    • JAVA IO包
    • JAVA NIO
    • Channel
    • Buffer
    • Selector
    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    九、JVM類加載機制

    • 加載、驗證、準備、解析
    • 符號引用、直接引用
    • 初始化
    • 類構造器<client>
    • 類加載器
    • 雙親委派
    • OSGI(動態模型系統)
    史上最全JVM大全詳解!java程序員細節到極致的一次,魔鬼

    最後

    關注小編+轉發文章+私信【JVM】免費獲取這個PDF資料喲!

    還有更多免費的Java架構學習資料,其中覆蓋了互聯網的方方面面,期間碰到各種產品各種場景下的各種問題,希望可以幫助大家擴展自己的技術廣度和知識面。


    分享到:


    相關文章: