1. 程式人生 > >java JVM的記憶體區域(執行時資料區域)

java JVM的記憶體區域(執行時資料區域)

JVM的記憶體形式:

 

(1)方法區:存放了要載入的類的資訊(名稱,修飾符等)、類中的靜態變數、類中定義為final的變數、類中Field資訊、類中的方法資訊,當開發人員通過Class物件的getName、isInterface方法來獲取資訊時候,這些資訊都來源於方法區。方法區域也是全域性共享的,在一定條件下它也會被GC,當方法區域要使用的記憶體超過其執行的大小時,會丟擲OutOfMemory資訊。調節大小使用-XX:PerSize-XX:MaxPerSize

(2)堆:用於存入物件例項和陣列值,所有的執行緒共享堆空間。

注意創建出來的物件只包含屬於各自的成員變數,並不包括成員方法。因為同一個類的物件擁有各自的成員變數,儲存在各自的堆中,但是他們共享該類的方法,並不是每建立一個物件就把成員方法複製一次。物件使用方法的時候方法才被壓入棧,方法不使用則不佔用記憶體。調節大小使用:

-Xms-Xmx

(3)本地方法棧:用於支援native方法的執行,儲存了每個native方法呼叫的狀態。

(4)PC暫存器和JVM方法棧:每個執行緒會建立自己的PC暫存器和JVM方法棧,所以PC暫存器和JVM方法棧為執行緒所私有。PC存放下一條指令在方法內的偏移量,棧中存放棧幀,每個方法每次呼叫都會產生棧幀,棧幀主要是分為區域性變數區和運算元棧兩個部分。區域性變數區用於存放方法中的區域性變數和引數,運算元棧存放方法執行過程中產生的中間結果。棧幀裡面還有一些雜用空間,例如方法已經解析常量池的引用。當JVM方法棧空間不足時,會丟擲StackOverflowError錯誤。

  本文引用自:深入理解

Java虛擬機器的第2章內容(全面)

  Java與C++之間有一堵由記憶體動態分配和垃圾收集技術所圍成的高牆,牆外面的人想進去,牆裡面的人卻想出來。

  概述:

  對於從事C和C++程式開發的開發人員來說,在記憶體管理領域,他們既是擁有最高權力的皇帝,又是從事最基礎工作的勞動人民—既擁有每

一個物件的“所有權”,又擔負著每一個物件生命開始到終結的維護責任。

  對於Java程式設計師來說,在虛擬機器的自動記憶體管理機制的幫助下,不再需要為每一個new操作去寫配對的delete/free程式碼,而且不容易出現

記憶體洩漏和記憶體溢位問題,看起來由虛擬機器管理記憶體一切都很美好。不過,也正是因為Java程式設計師把記憶體控制的權力交給了Java虛擬機器,一旦

出現記憶體洩漏和溢位方面的問題,如果不瞭解虛擬機器是怎樣使用記憶體的,那排查錯誤將會成為一項異常艱難的工作。

  執行時資料區域

  Java虛擬機器在執行Java程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。這些區域都有各自的用途,以及建立和銷燬的時

間,有的區域隨著虛擬機器程序的啟動而存在,有些區域則是依賴使用者執行緒的啟動和結束而建立和銷燬。根據《Java虛擬機器規範(第2版)》的規

定,Java虛擬機器所管理的記憶體將會包括以下幾個執行時資料區域,如下圖所示:

          

  程式計數器     

  程式計數器(Program Counter Register)是一塊較小的記憶體空間,它的作用可以看做是當前執行緒所執行的位元組碼的行號指示器。在虛擬

機的概念模型裡(僅是概念模型,各種虛擬機器可能會通過一些更高效的方式去實現),位元組碼直譯器工作時就是通過改變這個計數器的值來選取

下一條需要執行的位元組碼指令,分支、迴圈、跳轉、異常處理、執行緒恢復等基礎功能都需要依賴這個計數器來完成。 由於Java虛擬機器的多線

程是通過執行緒輪流切換並分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器(對於多核處理器來說是一個內

核)只會執行一條執行緒中的指令。因此,為了執行緒切換後能恢復到正確的執行位置,每條執行緒都需要有一個獨立的程式計數器,各條

執行緒之間的計數器互不影響,獨立儲存,我們稱這類記憶體區域為“執行緒私有”的記憶體。 如果執行緒正在執行的是一個Java方法,這個計數器

記錄的是正在執行的虛擬機器位元組碼指令的地址;如果正在執行的是Natvie方法,這個計數器值則為空(Undefined)。此記憶體區域是唯一一個

Java虛擬機器規範中沒有規定任何OutOfMemoryError情況的區域。

  Java虛擬機器棧

  與程式計數器一樣,Java虛擬機器棧(Java Virtual Machine Stacks)也是執行緒私有的,它的生命週期與執行緒相同。虛擬機器棧描述的是Java

方法執行的記憶體模型:每個方法被執行的時候都會同時建立一個棧幀(Stack Frame)用於儲存區域性變量表、操作棧、動態連結、方法出口

資訊。每一個方法被呼叫直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。

  經常有人把Java記憶體區分為堆記憶體(Heap)和棧記憶體(Stack),這種分法比較粗糙,Java記憶體區域的劃分實際上遠比這複雜。這種劃分

方式的流行只能說明大多數程式設計師最關注的、與物件記憶體分配關係最密切的記憶體區域是這兩塊。其中所指的“堆”在後面會專門講述,而所指

的“棧”就是現在講的虛擬機器棧,或者說是虛擬機器棧中的區域性變量表部分。

  區域性變量表存放了編譯期可知的各種基本資料型別(boolean、byte、char、short、int、float、long、double)、物件引用

(reference型別),它不等同於物件本身,根據不同的虛擬機器實現,它可能是一個指向物件起始地址的引用指標,也可能指向一個代表物件的

控制代碼或者其他與此物件相關的位置)和returnAddress型別(指向了一條位元組碼指令的地址)。

  其中64位長度的long和double型別的資料會佔用2個區域性變數空間(Slot),其餘的資料型別只佔用1個。區域性變量表所需的記憶體

空間在編譯期間完成分配,當進入一個方法時,這個方法需要在幀中分配多大的區域性變數空間是完全確定的,在方法執行期間不會改

變區域性變量表的大小。 在Java虛擬機器規範中,對這個區域規定了兩種異常狀況:如果執行緒請求的棧深度大於虛擬機器所允許的深度,將丟擲

StackOverflowError異常;如果虛擬機器棧可以動態擴充套件(當前大部分的Java虛擬機器都可動態擴充套件,只不過Java虛擬機器規範中也允許固定長度的

虛擬機器棧),當擴充套件時無法申請到足夠的記憶體時會丟擲OutOfMemoryError異常。

  本地方法棧

  本地方法棧(Native Method Stacks)與虛擬機器棧所發揮的作用是非常相似的,其區別不過是虛擬機器棧為虛擬機器執行Java方法(也就是字

節碼)服務,而本地方法棧則是為虛擬機器使用到的Native方法服務。虛擬機器規範中對本地方法棧中的方法使用的語言、使用方式與資料結構並沒

有強制規定,因此具體的虛擬機器可以自由實現它。甚至有的虛擬機器(譬如Sun HotSpot虛擬機器)直接就把本地方法棧和虛擬機器棧合二為一。與

虛擬機器棧一樣,本地方法棧區域也會丟擲StackOverflowError和OutOfMemoryError異常。

  Java堆

  對於大多數應用來說,Java堆(Java Heap)是Java虛擬機器所管理的記憶體中最大的一塊。Java堆是被所有執行緒共享的一塊記憶體區域,在虛擬機器啟動時建立。此內存區域的唯一目的就是存放物件例項,幾乎所有的物件例項都在這裡分配記憶體。這一點在Java虛擬機器規範中的描述是:所有的物件例項以及陣列都要在堆上分配,但是隨著JIT編譯器的發展與逃逸分析技術的逐漸成熟,棧上分配、標量替換優化技術將會導致一些微妙的變化發生,所有的物件都分配在堆上也漸漸變得不是那麼“絕對”了。

  Java堆是垃圾收集器管理的主要區域,因此很多時候也被稱做“GC堆”(Garbage Collected Heap,幸好國內沒翻譯成“垃圾堆”)。如果從記憶體回收的角度看,由於現在收集器基本都是採用的分代收集演算法,所以Java堆中還可以細分為:新生代和老年代;再細緻一點的有Eden空間、From Survivor空間、To Survivor空間等。如果從記憶體分配的角度看,執行緒共享的Java堆中可能劃分出多個執行緒私有的分配緩衝區(Thread Local Allocation Buffer,TLAB)。不過,無論如何劃分,都與存放內容無關,無論哪個區域,儲存的都仍然是物件例項,進一步劃分的目的是為了更好地回收記憶體,或者更快地分配記憶體。在本章中,我們僅僅針對記憶體區域的作用進行討論,Java堆中的上述各個區域的分配和回收等細節將會是下一章的主題。

  根據Java虛擬機器規範的規定,Java堆可以處於物理上不連續的記憶體空間中,只要邏輯上是連續的即可,就像我們的磁碟空間一樣。在實現時,既可以實現成固定大小的,也可以是可擴充套件的,不過當前主流的虛擬機器都是按照可擴充套件來實現的(通過-Xmx和-Xms控制)。如果在堆中沒有記憶體完成例項分配,並且堆也無法再擴充套件時,將會丟擲OutOfMemoryError異常。

  方法區

  方法區(Method Area)與Java堆一樣,是各個執行緒共享的記憶體區域,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。雖然Java虛擬機器規範把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做Non-Heap(非堆),目的應該是與Java堆區分開來。

  對於習慣在HotSpot虛擬機器上開發和部署程式的開發者來說,很多人願意把方法區稱為“永久代”(Permanent Generation),本質上兩者並不等價,僅僅是因為HotSpot虛擬機器的設計團隊選擇把GC分代收集擴充套件至方法區,或者說使用永久代來實現方法區而已。對於其他虛擬機器(如BEA JRockit、IBM J9等)來說是不存在永久代的概念的。即使是HotSpot虛擬機器本身,根據官方釋出的路線圖資訊,現在也有放棄永久代並“搬家”至Native Memory來實現方法區的規劃了。

  Java虛擬機器規範對這個區域的限制非常寬鬆,除了和Java堆一樣不需要連續的記憶體和可以選擇固定大小或者可擴充套件外,還可以選擇不實現垃圾收集。相對而言,垃圾收集行為在這個區域是比較少出現的,但並非資料進入了方法區就如永久代的名字一樣“永久”存在了。這個區域的記憶體回收目標主要是針對常量池的回收和對型別的解除安裝,一般來說這個區域的回收“成績”比較難以令人滿意,尤其是型別的解除安裝,條件相當苛刻,但是這部分割槽域的回收確實是有必要的。在Sun公司的BUG列表中,曾出現過的若干個嚴重的BUG就是由於低版本的HotSpot虛擬機器對此區域未完全回收而導致記憶體洩漏。 根據Java虛擬機器規範的規定,當方法區無法滿足記憶體分配需求時,將丟擲OutOfMemoryError異常。

  執行時常量池

  執行時常量池(Runtime Constant Pool)是方法區的一部分。Class檔案中除了有類的版本、欄位、方法、介面等描述等資訊外,還有一項資訊是常量池(Constant Pool Table),用於存放編譯期生成的各種字面量和符號引用,這部分內容將在類載入後存放到方法區的執行時常量池中。 Java虛擬機器對Class檔案的每一部分(自然也包括常量池)的格式都有嚴格的規定,每一個位元組用於儲存哪種資料都必須符合規範上的要求,這樣才會被虛擬機器認可、裝載和執行。但對於執行時常量池,Java虛擬機器規範沒有做任何細節的要求,不同的提供商實現的虛擬機器可以按照自己的需要來實現這個記憶體區域。不過,一般來說,除了儲存Class檔案中描述的符號引用外,還會把翻譯出來的直接引用也儲存在執行時常量池中。 執行時常量池相對於Class檔案常量池的另外一個重要特徵是具備動態性,Java語言並不要求常量一定只能在編譯期產生,也就是並非預置入Class檔案中常量池的內容才能進入方法區執行時常量池,執行期間也可能將新的常量放入池中,這種特性被開發人員利用得比較多的便是String類的intern()方法。 既然執行時常量池是方法區的一部分,自然會受到方法區記憶體的限制,當常量池無法再申請到記憶體時會丟擲OutOfMemoryError異常。

  物件訪問

  介紹完Java虛擬機器的執行時資料區之後,我們就可以來探討一個問題:在Java語言中,物件訪問是如何進行的?物件訪問在Java語言中無處不在,是最普通的程序行為,但即使是最簡單的訪問,也會卻涉及Java棧、Java堆、方法區這三個最重要記憶體區域之間的關聯關係,如下面的這句程式碼:

          Object obj = new Object();

假設這句程式碼出現在方法體中,那“Object obj”這部分的語義將會反映到Java棧的本地變量表中,作為一個reference型別資料出現。而“new Object()”這部分的語義將會反映到Java堆中,形成一塊儲存了Object型別所有例項資料值(Instance Data,物件中各個例項欄位的資料)的結構化記憶體,根據具體型別以及虛擬機器實現的物件記憶體佈局(Object Memory Layout)的不同,這塊記憶體的長度是不固定的。另外,在Java堆中還必須包含能查詢到此物件型別資料(如物件型別、父類、實現的介面、方法等)的地址資訊,這些型別資料則儲存在方法區中。

  由於reference型別在Java虛擬機器規範裡面只規定了一個指向物件的引用,並沒有定義這個引用應該通過哪種方式去定位,以及訪問到Java堆中的對

象的具體位置,因此不同虛擬機器實現的物件訪問方式會有所不同,主流的訪問方式有兩種:使用控制代碼和直接指標。 如果使用控制代碼訪問方式,Java堆中將會劃分出一塊記憶體來作為控制代碼池,reference中儲存的就是物件的控制代碼地址,而控制代碼中包含了物件例項資料和型別資料各自的具體地址資訊,如下圖所示:

      

  如果使用的是直接指標訪問方式,Java 堆物件的佈局中就必須考慮如何放置訪問型別資料的相關資訊,reference中直接儲存的就是物件地址,如下

圖所示:

      

  這兩種物件的訪問方式各有優勢,使用控制代碼訪問方式的最大好處就是reference中儲存的是穩定的控制代碼地址,在物件被移動(垃圾收集時移動物件是非常普遍的行為)時只會改變控制代碼中的例項資料指標,而reference本身不需要被修改。使用直接指標訪問方式的最大好處就是速度更快,它節省了一次指標定位的時間開銷,由於物件的訪問在Java中非常頻繁,因此這類開銷積少成多後也是一項非常可觀的執行成本。就本書討論的主要虛擬機器Sun HotSpot而言,它是使用第二種方式進行物件訪問的,但從整個軟體開發的範圍來看,各種語言和框架使用控制代碼來訪問的情況也十分常見。


問題:

問題一:物件引用的記憶體結構是什麼?

在Java中,物件的引用實際上是指向一個控制代碼的指標,該控制代碼包含一對指標,一個指標指向一張表,實際上該表也有兩個指標(一個指標指向了包含了物件的方法表,另一個指向了物件型別,表明該物件所屬的型別),另一個指標指向一塊從Java堆中分配的記憶體空間,該空間用於儲存物件資料。

參考:

[plain] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. 當Java虛擬機器執行時,它需要記憶體來存取很多東西。例如,位元組碼,從已經裝載的class檔案中得到的其他資訊,程式建立的物件,傳遞給方法的引數,返回值,區域性變數,已經運算的中間結果等。Java虛擬機器把這些資料都組織到幾個“執行時資料區”,以便於管理,主要包括方法區、堆、Java棧、PC暫存器、本地方法棧。  
  2. 方法區  
  3.       在Java虛擬機器中,關於被裝載的型別的資訊儲存在一個邏輯上被稱為方法區的記憶體中。當虛擬機器裝載某個型別時,它使用類裝載器定位相應的class檔案,然後讀入這個class檔案--------一個線性二進位制資料流--------然後把它傳輸到虛擬機器中。緊接著虛擬機器提取其中的型別資訊,並將這些資訊儲存到方法區。該型別中的類(靜態)變數同樣也儲存在方法區中。  
  4.        由於所有執行緒都共享方法區,因此它們對方法區資料的訪問必須被設計是執行緒安全的。比如,假設同時兩個執行緒都企圖訪問一個名為Lava的類,而這個類還沒有內裝載入虛擬機器,那麼,這時應該只有一個執行緒去裝載它,而另一個執行緒則只能等待。  
  5.        對每個裝載的型別,虛擬機器都會在方法區中儲存一下型別資訊:  
  6. l  這個型別的全限定名  
  7. l  這個型別的直接超類的全限定名(除了Object)  
  8. l  這個型別的是類型別還是介面型別  
  9. l  這個型別的訪問修飾符  
  10. l  任何直接超介面的全限定名的有序列表  
  11. 除了上面的基本資訊以外,虛擬機器還得為每個被裝載的型別儲存以下資訊:  
  12. l  該型別的常量池  
  13. l  欄位資訊  
  14. l  方法資訊  
  15. l  除了常量以外的所有類變數  
  16. l  一個到ClassLoader的引用  
  17. l  一個到Class類的引用  
  18. 指向ClassLoader的引用  
  19.        每個型別被裝載的時候,虛擬機器必須跟蹤它是由啟動類裝載器還是由使用者自定義類裝載器裝載的。如果是使用者自定義類裝載器裝載的,那麼虛擬機器必須在型別資訊中儲存對該型別裝載器的引用。這是作為方法表中的型別資料的一部分儲存的。  
  20.        虛擬機器會在動態連線期間使用這個資訊。當某個型別引用另一個型別的時候,虛擬機器會請求裝載發起引用的類裝載器來裝載被引用的型別。這個動態連線的過程,對於虛擬機器分離名稱空間的方式也是至關重要的。為了能夠正確執行動態連線以及維護多個名稱空間,虛擬機器需要在方法表中得知每個類都是哪個類裝載器裝載的。  
  21. 指向Class的引用  
  22. 對於每個被裝載的型別(不管是類還是介面),虛擬機器都會相應地為它在堆上建立一個java.lang.Class類的例項,而且虛擬機器還必須以某種方式把這個例項和儲存在方法區中的型別資料關聯起來。  
  23.        在程式中,可以使用指向Class物件的引用。Class類中的兩個方法可以得到任何已裝載的類的Class例項的引用。分別是Class.forName(“”)以及Class.getClass()。  
  24.        給出一個Class物件的引用,就可以通過Class類中的定義的方法來找出這個型別的相關資訊。如果檢視這些方法會很快意思到,Class類使得執行程式可以訪問方法區中儲存的資訊。下面的是Class類中宣告的方法:  
  25. public string getName();                     返回類的全限定名  
  26. public Class getSuperClass();        返回型別的直接超類例項(object或者介面返回null)  
  27. public boolean isInterface();         判斷該型別是否是介面  
  28. public Class[] getInterfaces();              返回一個Class物件陣列,每個Class物件對應一個直接超類介面,如果該型別沒有直接超介面,getInterfaces()返回一個0長度陣列  
  29. public ClassLoader getClassLoader();    返回該型別的ClassLoader物件的引用  
  30. 堆  
  31. Java程式在執行時建立的所有類實或陣列都放在同一個堆中。而一個Java虛擬例項中只存在一個堆空間,因此所有執行緒都將共享這個堆。  
  32. Java物件中包含的基本資料由他所屬的類及其所有超類宣告的例項變數組成。只要有一個物件引用,虛擬機器就必須能夠快速的定位物件例項的資料。另外,它也必須能通過該物件引用訪問相應的類資料(儲存於方法區的型別資訊)。因此在物件中通常會有一個指向方法區的指標。  
  33. 程式計數器  
  34.        每個執行中的Java程式,每一個執行緒都有它自己的PC暫存器,也是該執行緒啟動時建立的。PC暫存器的內容總是指向下一條將被執行指令的餓“地址”,這裡的“地址”可以是一個本地指標,也可以是在方法區中相對應於該方法起始指令的偏移量。  
  35. Java棧  
  36.        Java棧以幀為單位儲存執行緒的執行狀態。虛擬機器只會直接對Java棧執行兩種操作:以幀為單位的壓棧或出棧。  
  37.        和方法區和堆一樣,Java棧和幀在記憶體中也不必是連續的。幀可以分佈在連續的棧裡,也可以分佈在堆裡,或者兩者兼有的。  
  38.        棧幀  
  39.        棧幀由三部分組成:區域性變數、運算元棧和幀資料區。  
  40.        當虛擬機器呼叫一個Java方法時,它從對應類的而型別資訊中得到此方法的區域性變數區和運算元棧的大小,並據此分配棧幀記憶體,然後壓入Java棧中。  
  41.        區域性變數:存放區域性變數和方法引數  
  42.        運算元棧:執行緒的工作區,用來存放運算過程中的臨時資料  
  43.        幀資料區:儲存支援常量解析、正常方法返回以及異常派發機制的資料  
[plain] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. 執行時資料區域:  
  2. 包括 方法區,虛擬機器棧,本地方法棧,堆 和程式計數器。  
  3. 程式計數器:  
  4. 是一塊較小的記憶體空間,它的作用可以看作是當前執行緒所執行的位元組碼的行號指示器。  
  5. 每一個執行緒都有自己私有的程式計數器。  
  6. 如果執行緒正在執行的是一個JAVA方法,該計數器記錄的是正在執行的虛擬機器位元組碼指令的地址,如果正在執行的是native方法,則計數器值為空(undefined)。此記憶體區域是唯一一個在JAVA虛擬機器規範中沒有規定任何OutOfMemoryError情況的區域。  
  7. JAVA虛擬機器棧:  
  8. 也是執行緒私有的,生命週期和執行緒相同。每個方法被執行的時候都會同時建立一個棧幀(stack frame)用於儲存區域性變量表、操作棧、動態連結、方法出口等資訊。每個方法被呼叫直至執行完成的過程,就對應一個棧幀在虛擬機器棧中從入棧道出棧的過程。  
  9. 這個JAVA虛擬機器棧就是我們常說的“棧”。區域性變量表存放了元資料型別、引用型別  
  10. 區域性變量表所需的記憶體空間在編譯期間完成分配,當進入一個方法時,這個方法需要在幀中分配多大的區域性變數空間是完全確定的,在方法執行期間不會改變區域性變量表的大小。  
  11. 在JVM規範中,對這個區域規定了兩種異常情況:  
  12. 如果執行緒請求的棧深度大於JVM允許的深度,丟擲StackOverflowError  
  13. 如果虛擬機器棧可以動態擴充套件(目前大部分JVM都可動態擴充套件),當擴充套件時無法申請到足夠的記憶體時,會丟擲OutOfMemoryError異常  
  14. 本地方法棧:  
  15. 與虛擬機器棧作用類似,只不過前者是執行JAVA方法服務,而本地方法棧是為Native方法服務。  
  16. HotSpot將本地方法棧和虛擬機器棧合二為一。  
  17. 和虛擬機器棧一樣會丟擲來兩種異常。  
  18. JAVA堆:  
  19. JAVA堆是被所有執行緒共享的一塊記憶體區域,在JVM啟動時建立。其作用就是存放物件例項。  
  20. JVM規範規定:所有的物件例項及陣列都要在堆上分配。  
  21. JAVA堆也是垃圾回收管理的主要區域。  
  22. 由於現在收集器基本採用分代收集演算法,所以JAVA堆還可以細分為:新生代和老年代,再細分還有Eden空間、From Survivor空間、To Survivor空間。  
  23. 相關推薦

    java JVM記憶體區域執行資料區域

    JVM的記憶體形式:   (1)方法區:存放了要載入的類的資訊(名稱,修飾符等)、類中的靜態變數、類中定義為final的變數、類中Field資訊、類中的方法資訊,當開發人員通過Class物件的getName、isInterface方法來獲取資訊時候,這些資訊都來源於方

    Java記憶體區域執行資料區域記憶體模型JMM

    Java 記憶體區域和記憶體模型是不一樣的東西,記憶體區域是指 Jvm 執行時將資料分割槽域儲存,強調對記憶體空間的劃分。 而記憶體模型(Java Memory Model,簡稱 JMM )是定義了執行緒和主記憶體之間的抽象關係,即 JMM 定義了 JVM 在計算機記憶體(RAM)中的工作方式,如果我們要想深

    Java記憶體區域執行資料區域記憶體模型

        而記憶體模型(Java Memory Model,簡稱 JMM )是定義了執行緒和主記憶體之間的抽象關係,即 JMM 定義了 JVM 在計算機記憶體(RAM)中的工作方式,如果我們要想深入瞭解Java併發程式設計,就要先理解好Java記憶體模型。 Jav

    JVM:Run-Time Data Areas執行資料/ 記憶體區域

    一:前言 特別說明:文章中引用的圖片是通過谷歌的方式找到的,當時並沒有找到圖片是否擁有版權,如果遇到了的話,請告知博主,我會將相應的圖片刪除。 本部落格主要總結的是JVM的Run Time Data Areas(執行時資料區),也就是我們常說的記憶體區域。借

    JAVA記憶體區域記憶體溢位異常---------執行資料區域

    執行時資料區域 程式計數器、JAVA 虛擬機器棧、本地方法棧 以及方法區、堆 1 、Program Counter Register  較小的一塊記憶體空間,可看作是當前程式執行的位元組碼的行號指示器。多執行緒中,每個執行緒都需要一個獨立的計數器,各條執行緒的計數器互不

    JVM記憶體執行資料和直接記憶體 概念

    JVM記憶體分為5塊,其中1--3為執行緒隔離,4、5為執行緒共享。執行緒隔離:1、程式計數器:分支,迴圈跳轉、異常處理、執行緒恢復等作用(唯一一個沒有規定outofmemoryError的記憶體區)。2、VM stack,虛擬機器棧:主要用來存放區域性變量表(八種基本資料型

    JVM——記憶體區域執行資料區域詳解

    關注微信公眾號:CodingTechWork,一起學習進步。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200707122307227.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow

    Java虛擬機器之----瞭解“執行資料區域

    一、 前言 對於Java程式設計師來說,在虛擬機器自動記憶體管理機制的幫助下,不再需要像C/C++那樣為每一個new操作去寫配對的delete/free程式碼,不容易出現記憶體洩漏和記憶體溢位問題。 由虛擬機器管理記憶體雖然方便了程式設計師,不過,一旦出現這方面的問題,我們也必須學會

    JAVA虛擬機器JVM劃重點 第二章 Java記憶體區域記憶體溢位異常 之 執行資料區域

    本部落格參考《深入理解Java虛擬機器》(第二版)一書,提取重點知識,再加以個人的理解編寫而成。轉載請標明來源。 JVM劃重點 第二章 Java記憶體區域與記憶體溢位異常 之 執行時資料區域 概述 執行時資料區域 程式計數器 Java虛擬機

    JAVA虛擬機器執行記憶體劃分--執行資料區域

    Java虛擬機器在執行java程式時會把記憶體劃分為以下幾個不同的資料區域: java虛擬機器記憶體劃分(執行時)1、執行緒私有的:   程式計數器(Program Counter Register):可以看作當前執行緒所執行的位元組碼的行號指示器。java多執行緒中一個時刻,一個處理器都只會執行一條執

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

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

    【深入理解JVMJAVA執行資料區域

      JAVA中在由虛擬機器自動記憶體管理機制的幫助下,不需要在為每一個new操作區去寫配對的delete/free程式碼,不容易出現記憶體洩漏和記憶體溢位問題,有虛擬機器管理便很方便。但是如果不瞭解記憶體是如何控制的一旦出現了記憶體洩漏和記憶體溢位方面的問題,那麼排查錯誤便會非常艱

    JAVA執行資料區域記憶體區域記憶體溢位異常

    方法區(Method Area) 儲存內容用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。與執行緒的關係 各個執行緒共享該記憶體區域異常 這區域的記憶體回收目標

    JVM 記憶體區域 (執行資料區域)

    JVM 記憶體區域 (執行時資料區域) 連結:https://www.jianshu.com/p/ec479baf4d06   執行時資料區域 Java 虛擬機器在執行 Java 程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。這些區域都各有各自的用途,以及建立

    Java常見面試題—JVM執行資料區域

    JVM—執行時資料區域 JVM在執行JAVA程式時會把它管理的記憶體區域劃分為若干個不同的資料區域,統稱為執行時資料區,由圖可見JVM程式所佔的內可劃分成5個部分:程式計數器、虛擬機器棧(執行緒棧)、本地方法棧、堆(heap)和方法區(內含常量池),其中

    JVM執行資料區域 —— 程式計數器、Java虛擬機器棧、本地方法棧、Java堆、方法區、執行常量池

    java虛擬機器執行時資料區域的概括圖如下所示: 下面將對執行時資料區進行講解 程式計數器 1、說明:程式計數器可以看做是當前執行緒所執行的位元組碼的行號指示器。其實通俗點講就是記錄class檔案執行到哪一行 2、注意的點: (1)因為CPU執

    執行資料區域——JavaJava Heap

            對於大多數應用來說,Java堆(Java Heap)是Java虛擬機器所管理的記憶體中最大的一塊。Java堆是被所有執行緒共享的一塊記憶體區域,在虛擬機器啟動時建立。此記憶體區域的唯一目的就是存放物件例項,幾乎所有的物件例項都在這裡分配記憶體。這一點在

    JDK1.8-Java虛擬機器執行資料區域和HotSpot虛擬機器的記憶體模型

    官方文件規定的執行時資料區域 官方文件中規定的執行時資料區一共就幾塊: PC計數器, 虛擬機器棧, 本地方法棧, 堆區,

    JVM執行資料區域學習

    注:     1.本地方法棧和虛擬機器棧並非所有的JVM都有區分,不是強制規定,HotSpot中本地方法棧和虛擬機器棧是合在一起的;     2.方法區不等於永久代,HotSpot使用永久代來實現方

    JVM執行資料區域

    1. 程式計數器 程式計數器(Program Counter Register)是一塊較小的記憶體空間,它可以看做是當前執行緒所執行的位元組碼的行號指示器。在虛擬機器的概念模型裡(僅是概念模型,各種虛擬機器可能會通過一些更高效的方式去實現),位元組碼直譯器工作時就是通