深入理解java虛擬機--內存模型簡記

深入理解java虛擬機-內存模型簡記


寫在前面: 虛擬機自動內存管理的機制下,不需要爲每個new操作取寫配對的delete/free代碼,也不易出現內存泄漏和內存溢出問題。也正是因爲把控制內存的權力交給了java虛擬機,一旦出現內存泄漏,後果很嚴重。因此需要了解虛擬機是怎樣使用內存的。

Java虛擬機內存

運行時數據區

運行時數據區域

  • 程序計數器(線程私有)

  • 一塊較小的內存空間,可以看做是當前線程執行的字節碼行號的指示器。它是程序控制流的指示器,分支、循環、跳轉、異常處理、線程恢復都依賴計數器來完成。

    爲什麼是線程私有? java多線程的虛擬機是通過線程輪流切換、分配處理器執行時間的方式實現,因此,在切換線程時需要恢復正確的位置,所以每個線程都有一個獨立的程序計數器,線程之間計數器互不影響。
    執行java方法,計數器記錄的是正在執行的虛擬機字節碼指令的地址;
    執行本地方法,計數器爲undefined。
    沒有任何OutOfMemoryError的區域
    生命週期與線程相同

  • 虛擬機棧(線程私有)

    生命週期與線程相同,每個方法創建時都會創建一個棧幀用於存儲局部變量表、操作數棧、動態連接、方法出口等信息。
    局部變量存放編譯期可知的各種java虛擬機基本數據類型。
    線程請求的棧深度大於虛擬機所允許的深度,拋Stack Overflow Error
    棧擴展時無法申請到足夠內存會拋出out of memoryError

  • 本地方法棧(線程私有)
    本地方法棧與虛擬機棧類似,唯一不同的是兩者執行的服務不同,前者爲虛擬機使用的本地方法服務,而後者是爲虛擬機執行Java方法服務
    有的java虛擬機會把本地方法棧和虛擬機棧合二爲一。
    在棧深度溢出或擴展失敗時分別拋出Stack Overflow Error 或out of memoryError


  • 虛擬機管理內存中最大的一塊,java堆是被所有線程共享的一塊內存區域,虛擬機啓動時創建。
    用途:存放對象,幾乎 所有對象都在這裏分配內存。隨着java逃逸分析技術 的發展,有的對象也可能在棧中分配。
    java堆是垃圾收集器管理的內存區域。也叫“GC”堆,java堆中沒有完成內存實例分配且堆無法擴展時拋出OutOfMemoryError.
    逃逸分析技術:此處未作詳細說明,感興趣請參考如下這篇文章:

    https://blog.csdn.net/w372426096/article/details/80938788

  • 方法區
    線程共享。
    用途:用來存儲已被類加載的類型信息、常量、靜態變量、即時編譯器編譯後的代碼緩存等數據。
    別名 非堆,與java堆區分。
    一個變動:JDK7的HotSpot已經把原本放在永久代的字符串常量池、靜態變量等移出。到 JDK8完全廢棄了永久代的概念,改用元空間 代替
    方法區無法滿足新的內存需求分配時拋出OutOfMemoryError

    • 運行時常量池
      方法區的一部分。用於存放編譯期生成的各種字面量與符號引用,在類加載後放到方法去的運行時常量池中。
  • 其他
    直接內存:並不是虛擬機運行時的一部分
    NIO:基於通道緩衝區的I/O方式,使用Native函數庫直接分配堆外內存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章