1. 程式人生 > >深入理解Java虛擬機器 【jvm記憶體模型以及各個分割槽】

深入理解Java虛擬機器 【jvm記憶體模型以及各個分割槽】

1. JVM 記憶體模型

Java虛擬機器記憶體的各個區域包括:

  • 程式計數器
  • Java虛擬機器棧
  • 本地方法棧
  • Java堆
  • 方法區

2. 程式計數器

什麼是程式計數器呢?
  • 程式計數器是一塊較小的記憶體空間,它可以是當前程式所執行的位元組碼的行號指示器。

  • 注意:如果執行緒正在執行的是java的方法,這個計數器記錄的是正在執行的虛擬機器位元組碼指令的地址;如果正在執行的是Native方法,這個計數器值則為空(Undefined)。

程式計數器的作用
  • 位元組碼直譯器工作時,就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令,從而分支、迴圈、跳轉、異常處理、執行緒恢復等基礎功能都需要依賴此計數器來完成。

  • 在多執行緒的情況下,在任何一個確定的時刻,一個處理器都只會執行一條執行緒中的指令。執行緒切換後,能恢復到正確的執行位置。

程式計數器的特點
  • 是一塊較小的記憶體空間
  • “執行緒私有”;每條執行緒都有一個獨立的程式計數器,各個執行緒之間計數器互不影響,獨立儲存。
  • 是唯一一個在Java虛擬機器規範中沒有任何OutOfMemoryError情況的區域。

3. Java虛擬機器棧

什麼是Java虛擬機器棧?
  • 描述的是Java方法執行的記憶體模型。每個方法在執行的同時會建立一個棧幀用於儲存區域性變量表、運算元棧、動態連結、方法出口等。

  • 當方法在執行過程中需要建立區域性變數時,就將區域性變數的值存入棧幀的區域性變量表中,當這個方法執行完畢後,這個方法所對應的棧幀將會出棧,並釋放記憶體空間。

  • 注意: 人們常說,Java記憶體區分為,棧中存放區域性變數,堆中存放物件。這裡所說的只代表了Java虛擬機器棧中的區域性變量表部分。真正的Java虛擬機器棧是由一個個棧幀組成,每個棧幀都擁有:區域性變量表、運算元棧、動態連結、方法出口資訊。

Java虛擬機器棧的特點
  • 區域性變量表的建立是在方法被執行的時候,隨著棧幀的建立而建立。而且,區域性變量表所需的記憶體空間在編譯期間完成分配,當進入一個方法需要在幀中分配多大的區域性變數空間是完全確定的,在方法 執行期間不會改變區域性變量表的大小。

  • 如果執行緒請求的棧深度大於虛擬機器所允許的深度,將丟擲StackOverflowError

    異常;如果虛擬機器棧可以動態擴充套件,如果擴充套件時無法申請到足夠的記憶體,就會丟擲OutOfMemoryError異常。

  • Java虛擬機器棧也是執行緒私有的,每個執行緒都有各自的Java虛擬機器棧,而且隨著執行緒的死亡而死亡。

  • 注意: StackOverFlowErrorOutOfMemoryError的異同。
    StackOverFlowError 表示當前執行緒申請的棧超過了事先定好的棧的最大深度,但記憶體空間肯還有很多。而OutOfMemoeryError是指當執行緒申請棧時發現棧已經滿了,而且記憶體也都用光了。

本地方法棧

什麼是本地方法棧?
  • 本地方法棧與虛擬機器棧所發揮的作用是非常相似的,他們的區別是虛擬機器棧為虛擬機器執行Java方法服務,而本地方法棧則為虛擬機器使用到 的Native方法服務。

  • 本地方法被執行的時候,在本地方法棧也會建立一個棧幀,用於存放該本地方法的區域性變量表、運算元棧、動態連結、出口資訊。

  • 方法執行完畢後相應的棧幀也會出棧並釋放記憶體空間。也會丟擲StackOverFlowErrorOutOfMemoryError異常。

Java堆

什麼是堆?
  • java 堆是Java虛擬機器所管理的記憶體中最大的一塊,被所有執行緒共享的區域,存放物件例項,幾乎所有物件例項都在這裡分配記憶體。
堆的特點
  • 執行緒共享:整個java虛擬機器只有一個堆,所有的執行緒都訪問同一個堆。而程式計數器、java虛擬機器棧、本地方法棧都是一個執行緒對應一個。

  • 線上程啟動時被建立。

  • 垃圾收集器管理的主要區域。

  • Java堆中還可以細分為:新生代和老年代,再細緻一點有:Eden空間、From Survivor空間、To Survivor空間。不同的區域存放具有不同宣告週期的物件。這樣可以根據
    不同的區域使用不同的垃圾回收演算法,從而更具有針對性,從而更加高效。

  • java-堆裡面的分割槽:Eden,survival(from) to,老年代,各自的特點。

    • Eden區
      Eden區位於Java堆的年輕代,是新物件分配記憶體的地方,由於堆是所有執行緒共享的,因此在堆上分配記憶體需要加鎖。而Sun JDK為提升效率,會為每個新建的執行緒在Eden上分配一塊獨立的空間由該執行緒獨享,這塊空間稱為TLAB(Thread Local Allocation Buffer)。在TLAB上分配記憶體不需要加鎖,因此JVM在給執行緒中的物件分配記憶體時會盡量在TLAB上分配。如果物件過大或TLAB用完,則仍然在堆上進行分配。如果Eden區記憶體也用完了,則會進行一次Minor GC(young GC)。

    • Survival from to
      Survival區與Eden區相同都在Java堆的年輕代。Survival區有兩塊,一塊稱為from區,另一塊為to區,這兩個區是相對的,在發生一次Minor GC後,from區就會和to區互換。在發生Minor GC時,Eden區和Survivalfrom區會把一些仍然存活的物件複製進Survival to區,並清除記憶體。Survival to區會把一些存活得足夠舊的物件移至年老代。

    • 年老代
      年老代裡存放的都是存活時間較久的,大小較大的物件,因此年老代使用標記整理演算法。當年老代容量滿的時候,會觸發一次Major GC(full GC),回收年老代和年輕代中不再被使用的物件資源。

  • 執行緒共享的java堆可能劃分出多個執行緒私有的分配緩衝區,儲存的都是物件例項,進一步劃分的目的是為了更好的回收記憶體,更快的分配記憶體。

  • 堆的大小既可以實現固定大小的,也可以是可擴充套件的。主流的虛擬機器都是按照可擴充套件的來實現的。當執行緒請求分配記憶體,但堆中沒有記憶體完成例項分配,並且堆也無法擴充套件時,將會丟擲OutOfMemoryError

方法區

什麼是方法區?
  • 描述為堆的一個邏輯分割槽,別名:Non-Heap(非堆)。
  • 是各個執行緒共享的記憶體區域,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯後的程式碼等資料。
方法區特點
  • 執行緒共享,方法區是堆的一個邏輯分割槽,和堆一樣,都是執行緒共享的,整個虛擬機器中只有一個方法區。

  • 永久代,方法區中的資訊一般需要長期存在而且它又是堆的邏輯分割槽,因此用堆的劃分方法,我們把方法區成為老年代

  • 記憶體回收效率低,方法區中的資訊一般需要長期存在,回收一遍記憶體之後可能只有少量資訊無效。對方法區的記憶體回收的主要目標是:對常量池的回收和型別的解除安裝。

  • Java虛擬機器規範對方法區的限制非常寬鬆,和java堆一樣不需要連續的記憶體和可以選擇固定的大小或者可擴充套件,還可以不實現垃圾收集。

什麼是執行常量池?

  • 方法區中存放 三種資料:類資訊、常量、靜態變數、即時編譯後的程式碼。其中常量儲存在執行時常量池中。

  • 我們一般在一個類中通過public static final來宣告一個常量。這個類被編譯後便生成Class檔案,這個類的所有資訊都儲存在這個class檔案中。

  • 當這個類被Java虛擬機器載入後,class檔案中的常量就存放在方法區的執行時常量池中。而且在執行期間,可以向常量池中新增新的常量。如:String類的intern()方法就能在執行期間向常量池中新增字串常量。

  • 執行時,常量池是方法區的一部分,自然受到方法區記憶體的限制,當常量池無法再申請到記憶體時會丟擲OutOfMemoryError異常。

直接記憶體

  • 直接記憶體是除java虛擬機器之外的記憶體,但也可能被java使用。

  • 在NIO中引入了一種基於通道和緩衝的IO方式。它可以通過呼叫本地方法直接分配Java虛擬機器之外的記憶體,然後通過一個儲存在Java堆中的DirectByteBuffer物件直接操作該記憶體,而無需先將外面記憶體中的資料複製到堆中再操作,從而提升了資料操作的效率。

  • 直接記憶體的大小不受Java虛擬機器控制,但既然是記憶體,當記憶體不足時就會丟擲OOM異常。

相關推薦

深入理解Java虛擬機器 jvm記憶體模型以及各個分割槽

1. JVM 記憶體模型 Java虛擬機器記憶體的各個區域包括: 程式計數器 Java虛擬機器棧 本地方法棧 Java堆 方法區 2. 程式計數器 什麼是程式計數器呢? 程式

深入理解Java虛擬機器(二) --- JVM記憶體管理

執行時的資料區域 一.程式計數器 目的:作為當前執行緒所執行位元組碼的行號指示器 原理:通過位元組碼直譯器改變計數器的值來選取下一條位元組碼指令 特點: 1.佔用較小的記憶體空間 ​ 2.每條執行緒需要一個獨立的程式計數器 ​ 3.

視訊:深入理解Java虛擬機器jvm效能調優+記憶體模型+虛擬機器原理)共110集

龍果學院深入理解Java虛擬機器(Jvm效能調優+記憶體模型+虛擬機器原視訊 Java虛擬機器視訊教程一套不錯的視訊,課程一共有110課,課程目錄較多隻展示部分出來,喜歡的朋友下載看下 課程目錄(課程較多,只展示部分目錄) 課程大綱 第1節說在前面的話 [免費觀看]

[連載] 深入理解Java虛擬機器JVM高階特性與最佳實踐)之 走近Java

連載目錄 :    http://blog.csdn.net/u010903284/article/details/53117958 1.1 Java概述:               Java 不僅僅是一門程式語言,還是一個由一系列計算機軟體和規範形成的技術體系,這個技

深入理解java虛擬機器之自動記憶體管理機制(二)

垃圾收集演算法     java中的記憶體是交給虛擬機器管理的。要實現垃圾回收,必須考慮如下三個問題:     1. 哪些記憶體需要回收?     2. 什麼時候回收?     3. 怎麼回收?     對於第一點,往大了來說,是堆和方法區的記憶體需要回收。往具體了來說,是堆中哪些物件的記憶體可以回

深入理解java虛擬機器之自動記憶體管理機制(三)

  各類垃圾收集器與GC日誌 (一)垃圾收集器   一、Serial收集器     最基本、歷史最悠久的收集器。使用複製演算法,用在新生代,通常老年代用Serial old配合。GC過程需要stop the world。適用於client模式下的虛擬機器。   二、ParNew收集器  

深入理解java虛擬機器之自動記憶體管理機制(四)

記憶體分配與回收策略 (一)記憶體分配策略     給誰分配?分配到哪?是記憶體分配策略必須解答的問題。     java物件是分配的物件,往大方向來說,是分配到堆中,更細一點說,根據物件不同的特點分配到新生代和老年代區域。如果啟動了本地執行緒分配緩衝,就按執行緒優先在TLAB上分配。     一、新

深入理解java虛擬機器JVM調優配置

轉載文章:http://blog.csdn.net/sivyer123/article/details/17139443 堆記憶體設定 原理 JVM堆記憶體分為2塊:Permanent Space 和 Heap Space。 Permanent 即 持久代(Pe

深入理解Java虛擬機器JVM高階特性與最佳實踐pdf

下載地址:網盤下載目錄:前言第一部分 走近Java第1章 走近Java1.1 概述1.2 Java技術體系1.3 Java發展史1.4 Java虛擬機發展史1.4.1 Sun Classic Exact VM1.4.2 Sun HotSpot VM1.4.3 Sun Mobi

深入理解Java虛擬機器系列——JVM的GC理論詳解

GC的概念    GC:Garbage Collection 垃圾收集。這裡所謂的垃圾指的是在系統執行過程當中所產生的一些無用的物件,這些物件佔據著一定的記憶體空間,如果長期不被釋放,可能導致OOM(堆溢位)。記憶體區域中的程式計數器、虛擬機器棧、本地方法棧這3個區域隨著執行

深入理解Java虛擬機器》- JVM如何進行異常處理

一、Java異常 在程式中,錯誤可能產生於程式設計師沒有預料到的各種情況,或者超出程式設計師可控範圍的環境,例如使用者的壞資料、試圖開啟一個不存在的檔案等。為了能夠及時有效地處理程式中的執行錯誤,Java 專門引入了異常類。 二、Java常見異常分類 三、為什麼產生異常 在 Java 中一個異常的產生,主要

深入理解Java虛擬機器》- JVM是如何實現反射的

Java反射學問很深,這裡就淺談吧。如果涉及到方法內聯,逃逸分析的話,我們就說說是什麼就好了。有興趣的可以去另外看看,我後面可能也會寫一下。(因為我也不會呀~) 一、Java反射是什麼? 反射的核心是JVM在執行時才動態載入類或呼叫方法/訪問屬性,它不需要事先(寫程式碼的時候或編譯期)知道執行物件是誰。 反

學習筆記1:深入理解Java虛擬機器——JVM高階特性與最佳實踐_OOM(記憶體溢位)_虛擬機器引數設定_MAT

eclipse中設定debug標籤頁的vm引數 1,Run->Debug configurations->Java Application 2,選中已經寫好的專案 3,Arguments->VM arguments 4,在VM arguments 裡面就可以對虛擬機器的

學習筆記1:深入理解Java虛擬機器——JVM高階特性與最佳實踐_走進java_java記憶體區域與記憶體溢位異常

第一部分:走進java Java虛擬機器 程式碼在華章下載 jdk釋出了六個命令列工具和兩個視覺化故障處理工具。 推薦書籍 設計原本 領域特定語言 現在著名的Java虛擬機器 hotspot vm(預設) jrockit vm j9 vm jdk sun jdk op

Java深入理解Java虛擬機器」學習筆記(2)-記憶體管理

 一、執行時資料區   JVM在執行Java程式的時候,將其執行時資料區劃分為若干不同區域。它們的用途和建立及銷燬的時間不同。      1、程式計數器(Program Counter Register)     是一塊很小的記憶體空間。當執行緒執行的是Java方法,它記錄的是當前正在執行的

深入理解Java虛擬機器JVM高階特性與實踐 周志明 著》之第2章 Java記憶體區域與記憶體溢位異常

1、Java虛擬機器所管理的記憶體包括以下幾個執行時資料區域: 2、程式計數器:          1. 可以看作是當前執行緒所執行的位元組碼的行號指示器,是一塊較小的記憶體空間;  &nbs

深入理解JAVA虛擬機器2:JVM記憶體結構

記憶體結構一覽 在上一篇文章中,我們最後給出了一幅圖 這幅圖中,就包含了JVM的記憶體結構的所有組成元素,他們分別是:java堆記憶體、java棧、方法區、本地方法區以及pc暫存器,接下來我們就對這些區域逐一介紹。 java堆       Java堆是Java虛擬

JVM垃圾收集器與記憶體分配策略(總結自《深入理解Java虛擬機器》)

1、物件可用性判斷 垃圾收集器在回收物件前,需要判斷哪些物件沒有被廢棄,哪些物件已經廢棄了(即無法通過任何途徑使用的物件)。所以,垃圾收集器需要一種演算法來判定這個物件是否需要回收。 (1)引用計數演算法 引用計數演算法的基本思想是給一個物件新增一個引用計數器,

深入理解JAVA虛擬機器學習筆記(一)JVM記憶體模型

一、JVM記憶體模型概述 JVM記憶體模型其實也挺簡單的,這裡先提2個知識點: 1、組成:java堆,java棧(即虛擬機器棧),本地方法棧,方法區和程式計數器。 2、是否共享:其中方法區和堆區是執行緒共享的,虛擬機器棧,本地方法棧和程式計數器是執行緒私有的,也稱執行緒

深入理解java虛擬機器第0集--Java記憶體區域和java記憶體模型

首先我們清楚【記憶體區域】和【記憶體模型】是兩個不一樣的概念。當時我電面阿里的時候,面試官讓我講講記憶體模型的理解,我巴拉巴拉說了一通方法區-堆分割槽,垃圾演算法,面試官耐心的聽我說完就把電話掛了。 【記憶體區域】對應的是jvm程序。jvm啟動之後,自身是一個大的程序,作業