1. 程式人生 > >java自動記憶體管理機制

java自動記憶體管理機制

java自動記憶體管理

1.執行時的資料區域

         java程式在執行的過程中把它所管理的記憶體劃分為若干個區域分別是:

         1. 方法區    

   2. 虛擬機器棧      

   3. 本地方法棧      

   4,堆        

   5.程式計算器

2.程式計算器

        程式計數器是一塊小的記憶體空間,主要用來記錄所執行位元組碼的行號。

3.java虛擬機器棧

       java虛擬機器棧是執行緒私有的,生命週期和執行緒一致。虛擬機器棧描述的是java方法執行的記憶體模型:每個java方法在執行的同時會建立一個java虛擬機器棧,用於儲存變量表,運算元,動態連結串列,方法出口等資訊。

3.1 StackOverflowError 和 OutOfMemoryError的區別?

      stackOverflowError: 當執行緒請求的棧深度大於虛擬機器所允許的深度。

      OutOfMenoryError:  如果拓展時無法申請到足夠的記憶體,就會丟擲OutofmemoryError異常

4.本地方法棧

       本地方法棧基本與java虛擬機器棧的形式是一樣的,但是唯一的區別是虛擬機器棧為虛擬機器執行的java方法,但是本地方法棧為虛擬機器虛擬機器使用的Native方法服務。

       Native方法介紹: 點選開啟連結

5.java堆(GC堆)

       1.java堆是被所有執行緒所共享的一塊記憶體區域,在虛擬機器啟動的時候建立,主要時存放物件例項。

       2.java堆因為時垃圾收集器所管理的主要區域,因此也叫作GC堆。java堆根據垃圾回收演算法的不同又分為了,新生堆和老年代。

6.方法區(Non-Heap非堆)

      方法區跟Java堆一樣,是各個執行緒所共享的一塊記憶體區域,用於儲存虛擬機器載入的類資訊,常量,靜態變數,即時編譯器編譯後的程式碼等資料。

7.直接記憶體

      直接記憶體並不是java虛擬機器執行時的資料區的一部分,也不是虛擬機器規範中定義的記憶體區域。

      在jdk1.4中新加入的NIO,引入了一種給予通道與緩衝區的I / O方式,他可以直接使用Native函式庫直接分配堆外記憶體,然後通過一個儲存DirectbyteBuffrer物件作為這塊記憶體的引用進行操作,在一些場景中發揮高的效能,避免了java堆和Native堆中來回複製資料

  在jdk1.4中新加入的NIO,引入了一種給予通道與緩衝區的I / O方式,他可以直接使用Native函式庫直接分配堆外記憶體,然後通過一個儲存DirectbyteBuffrer物件作為這塊記憶體的引用進行操作,在一些場景中發揮高的效能,避免了java堆和Native堆中來回複製資料

8.物件的建立

8.1物件建立的過程


  1.虛擬機器遇到new指令時,首先檢查這個指令的引數是否在常量池中一個類的符號引用,並且去檢查這個符號的引用是否已經被載入,解析或者是被初始化過。

  2.如果沒有,就要進行類載入的操作

  3.類載入後就要為新物件分配記憶體

  4.記憶體分配完成後,虛擬機器需要將分配到的記憶體空間都初始化為零值(不包括物件頭)

  5.虛擬機器要對物件進行必要的設定。例如這個物件是哪個類的例項,如何找到物件的頭元素,物件的雜湊碼,物件的GC分代資訊等等。(對於虛擬機器來說已經結束物件的建立,但是對於java程式來說,還要執行init方法)

8.2物件的記憶體分配


  物件的記憶體分配分為兩種方法:

  1.指標碰撞法:將記憶體分為了兩種,空閒的記憶體和已經分配的記憶體,並且java堆絕對時規整的,並且用一個指標將空閒的記憶體和被分配的記憶體分割開,分配記憶體的過程就是將指標移動被分配物件大小的操作。

  2.空閒列表法:如果java堆不是規整的,已使用的記憶體空間和空閒的記憶體空間交錯相間,這時虛擬機器需要建立一個空間列表去記錄那些記憶體塊時可用的,那些記憶體塊是不可用的。

  ps:Java堆是否規整取決於採用的垃圾收集器是否具有壓縮規整的功能決定的。
8.2.1物件記憶體分配中出現的問題

  在併發的過程中不是執行緒安全的(可能出現正在給A分配記憶體但是還沒有結束又使用了舊的指標去給新的B分配記憶體)

  解決方法:

  1.一種是對分配記憶體空間的動作進行同步的處理--實際上是虛擬機器採用的CAS配上失敗重試的方法保證更新操作的原子性

  2.把記憶體分配的動作按照執行緒劃分在不同的空間之中進行,每個執行緒在Java堆中預先分配一小塊記憶體,稱為本地執行緒分配緩衝TLAB,那個執行緒需要分配記憶體就在那個執行緒的TLAB上進行分配,只有在TLAB使用完之後分配新的TLAB,才需要同步鎖定

9.物件的記憶體佈局

  物件在記憶體中儲存的佈局可以分為3塊區域:

   1.物件頭

   2.例項資料

   3.對齊填充

9.1物件頭

  1.一部分是用於儲存物件自身的執行時的資料,如雜湊碼,GC分代年齡...

  2.另一部分是型別指標,即物件指向它的類元資料的指標,虛擬機器通過這個指標來確定這個物件時那個類的例項。

9.2對齊填充

  對齊填充並不是必然的存在,沒有特別的含義,它僅僅起著佔位符的作用。

10.物件的訪問定位

  建立物件是為了使用物件,在java中設定了一個reference物件來操作堆上的具體物件,reference物件如何去訪問具體的物件呢,具體有兩種的方法:

  1.使用控制代碼:reference棧 --》  控制代碼池(包含了到物件例項資料的指標) --》 物件型資料

  2.reference棧 --》 直接指向物件型別資料

  優勢:

  控制代碼
:reference中儲存的時穩定的控制代碼地址,在物件被移動的時候只要改變控制代碼中的例項資料的指標,reference本身不需要被修改

  直接指標:訪問的速度比較塊,節省了一次的指標訪問開銷,在Sun HotSpot中使用的是直接指標

相關推薦

java自動記憶體管理機制

java自動記憶體管理 1.執行時的資料區域          java程式在執行的過程中把它所管理的記憶體劃分為若干個區域分別是:          1. 方法區        2. 虛擬機器棧          3. 本地方法棧          4,堆     

三、Java虛擬機器自動記憶體管理機制、物件建立及記憶體分配

  1、物件是如何建立: 步驟:    (1)、虛擬機器遇到new <類名>的指令---->根據new的引數是否在常量池中定位一個類的符號引用    (2)、檢測該符號引用代表的類是否已經被載入、解析、和初始化。(如果沒有則

自動記憶體管理機制(1)- java記憶體區域與虛擬機器物件

自動記憶體管理機制(1)- java記憶體區域與虛擬機器物件 1. 執行時資料區域 Java虛擬機器在執行Java程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。有的區域隨著虛擬機器進行的啟動而存在,有些區域則以來使用者執行緒的啟動和結束而建立和銷燬。 有以下幾個區域

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

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

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

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

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

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

Java虛擬機器筆記-1(Java技術體系&自動記憶體管理機制&記憶體區域與記憶體溢位&垃圾收集器與記憶體分配策略)

世界上沒有完美的程式,但寫程式是不斷追求完美的過程。 Devices(裝置、裝置)、GlassFish(商業相容應用伺服器) 目錄 1. Java技術體系包括: Java技術體系的4個平臺 虛擬機器分類 HotSpot VM 模組化、混合程式設計 多核並行

二、Java虛擬機器自動記憶體管理機制、執行時資料區域深入瞭解

執行時資料區域:     (1)、程式計數器         a、定義:是一塊較小的記憶體空間,可以看作是當前執行緒所執行的位元組碼的行號指示器。         b、執行緒私有:因為多執行緒是通過執行緒輪流切換並且分配處理器執行時間的方式來實現的,任何時刻,        

深入理解Java虛擬機器——自動記憶體管理機制

特此申明: 前段時間找工作所以看了這本書,整理的時候除了參考網上已有的筆記貼,加上自己整合的,可能和別人有雷同之處。不過無所謂啦,寫出來自己看看,需要的朋友參考下,僅此而已。 一:Java記憶體區域與記憶體溢位異常        在執行Java程式時,Java虛擬機器會

java虛擬機器自動記憶體管理機制

public class FinalizeEscapeGC{          public static FinalizeEscapeGC SAVE_HOOK = null;        // 靜態屬性引用,作為GC Roots     public void isAlive () {        

筆記二(自動記憶體管理機制)-Java記憶體區域與記憶體溢位異常

1 執行時資料區域      Java虛擬機器在執行Java程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。這些區域都有各自的用途,以及建立和銷燬的時間,有的區域隨著虛擬機器程序的啟動而存在,有些區域則是依賴使用者執行緒的啟動和結束而建立和銷燬。1.1 程式計數器

Java虛擬機器之自動記憶體管理機制

Java與C++之間有一堵由記憶體動態分配和垃圾收集技術所圍城的高牆,牆外面的人想進去,牆裡面的人卻想出來。Java憑藉虛擬機器自動記憶體管理機制,不需要為每一個new操作去配對free的操作,不容易出現記憶體洩露和記憶體溢位問題。但是我們還是很有必要了解虛擬機器是怎麼使用記

自動記憶體管理機制(5)- 虛擬機器效能監控

自動記憶體管理機制(5)- 虛擬機器效能監控 0. 概述 在我們日常開發的專案中,有時經常會碰到以下問題: OOM(OutOfMemoryError),記憶體不足 記憶體洩漏 執行緒死鎖 Lock Contention,鎖爭用 Java程序消耗CP

自動記憶體管理機制(4)- 記憶體分配和回收策略

自動記憶體管理機制(4)- 記憶體分配和回收策略 Java所承諾的自動記憶體管理主要是針對物件記憶體的回收和物件記憶體的分配。 在Java虛擬機器的五塊記憶體空間中,程式計數器、Java虛擬機器棧、本地方法棧記憶體的分配和回收都具有確定性,一般在編譯階段就能確定需要分配的記憶體大小,

自動記憶體管理機制(3)-HotSpot垃圾收集器

自動記憶體管理機制(3)-HotSpot垃圾收集器 如果說收集演算法是記憶體回收的方法論,那麼垃圾收集器就是記憶體回收的具體實現。 這裡討論的收集器都是JDK1.7(包含JDK1.7)以後的HotSpot虛擬機器: 上半部屬於新生代收集器,下半部屬於老年代收集器。如果兩個收集器

自動記憶體管理機制(2)- 記憶體回收和垃圾收集演算法

自動記憶體管理機制(2)- 記憶體回收和垃圾收集演算法 1. 概述 首先思考三個問題: 哪些記憶體需要回收 什麼時候回收 如何回收 程式計數器、虛擬機器棧、本地方法棧是執行緒私有的,因此這幾個區域的記憶體分配和回收都具有確定性(執行緒結束時執行垃圾回

JVM介紹&自動記憶體管理機制

  1.介紹JVM(Java Virtual Machine,Java虛擬機器)      JVM是Java Virtual Machine的縮寫,通常成為java虛擬機器,作為Java可以進行一次編寫,到處執行(Write once, run anywhe

深入理解JVM(二)自動記憶體管理機制

2.1 C、C++記憶體管理是由開發人員管理,而Java則交給了JVM進行自動管理 2.2 JVM執行時資料區:方法區、堆(執行時執行緒共享),虛擬機器棧、本地方法棧、程式計數器(執行時執行緒隔離,私有)   2.2.1 程式計數器(Program Counter Register):每一個執行緒都獨有一

深入理解JVM虛擬機器-2自動記憶體管理機制

java虛擬機器所管理的記憶體將會包括一下幾個執行時資料區域。 程式計數器: 程式計數器是一塊較小的記憶體空間。位元組碼解析式工作時就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令,分支、迴圈、跳轉、異常處理、執行緒恢復等基礎功能都需要依賴這個計數器來

JVM學習(1) 自動記憶體管理機制

Java記憶體區域與記憶體溢位異常 Java和C++之間有一堵由記憶體動態分配和垃圾手機技術所圍成的高牆,牆外面的人想進去,牆裡面的人卻想出來。 概述 對於從事C和C++程式開發的開發人員來說,在記憶體管理領域,他們即是擁有最高權力的皇帝,又是從事最基礎工作的勞動人民——既有用每一個物件的“所有權”,又