1. 程式人生 > >1.JVM原理、java記憶體分析

1.JVM原理、java記憶體分析

目錄

JVM原理

記憶體分析

共享

獨有

JVM原理

JVM生命週期:一個執行中的Java虛擬機器有著一個清晰的任務:執行Java程式。你在同一臺機器上執行三個程式,就會有三個執行中的Java虛擬機器。

Main()方法是程式的起點,程式中其他的執行緒都由他來啟動。

  • 每一個Java虛擬機器都包含方法區(method area)和(heap),所有執行緒共享
  • 當一個執行緒被建立時,會被分配只屬於他自己的PC暫存器“pc register”(程式計數器)和Java(Java stack)。在HotSopt虛擬機器中直接就把本地方法棧和Java棧合二為一。

JVM記憶體回收:Sun的JVMGenerationalCollecting(垃圾回收)原理是這樣的:把物件分為年青代(Young)、年老代(Tenured)、持久代(Perm),對不同生命週期的物件使用不同的演算法。(基於對物件生命週期分析)

垃圾回收器要回收物件的時候,首先要呼叫這個類的finalize()方法

通常我們說的JVM記憶體回收是在指堆記憶體回收,確實只有堆中的內容是動態申請分配的,所以以上物件的年輕代和年老代都是指的JVM的Heap空間,而持久代則是之前提到的MethodArea,不屬於Heap。

記憶體分析

共享

 Java虛擬機器載入並解析一個類以後,將從類檔案中解析出來的資訊儲存與方法區

中。程式執行時建立的物件都儲存在中。

1.堆記憶體(heap):

儲存物件資料,提供所有類例項(new出的物件)和陣列物件儲存區域。堆中不存放基本型別和物件引用,只存放物件本身,jvm只有一個堆區,物件被使用完不會馬上消失,等待垃圾回收器不定時回收。

2.方法區(資料共享區/靜態區)(method):

方法區包含所有的class資訊static變數、常量池。方法區中包含的都是在整個程式中永遠唯一的元素,如class,static變數。執行時常量池都分配在 Java 虛擬機器的方法區之中。隨著JVM的開啟而產生,在JVM結束時而消失的,生命週期和jvm一致。

2.1 常量池:

常量池指的是在編譯期被確定,並被儲存在已編譯的.class檔案中的一些資料。除了包含程式碼中所定義的各種基本型別(如int、long等等)和物件型(如String及陣列)的常量值(final)還包含一些以文字形式出現的符號引用,比如:

  1. 類和介面的全限定名
  2. 欄位的名稱和描述符
  3. 方法和名稱和描述符

如果是編譯期已經建立好(直接用雙引號定義的)的就儲存在常量池中,如果是執行期(new出來的)才能確定的就儲存在堆中。

獨有

PC暫存器中儲存執行緒執行的下一條指令。Java儲存了一個執行緒呼叫方法時的狀態,包括本地變數、呼叫方法的引數、返回值、處理的中間變數。

1.棧記憶體(stack)

每個執行緒都有自己獨有的一個棧區,出了作用域馬上消失釋放空間。

儲存區域性變數,只儲存基礎資料型別的物件和自定義物件的引用,基本資料型別(char,byte,short,int,long,float,double,boolean)的變數、引用資料型別(reference型別)

2.PC暫存器

建立字串記憶體分析:

字串常量池屬於方法區中的一塊。

String str = "hello"    這個語句會先檢查字串常量池是否存放這個"hello"這個字串物件,如果沒有存在,那麼就會在字串常量池中建立這個字串物件,如果存在直接返回該字串的記憶體地址值。
String str = new String("hello")     該語句會建立兩個物件:首先會先檢查字串常量池中存不存在"hello"這個字串物件,如果不存在就會建立,如果存在就不會建立。然後new String這個語句就會在堆記憶體中開闢一個字串物件,把字串常量池中的"hello"字串內容拷貝至堆記憶體中的字串物件,然後返回堆記憶體中字串物件的記憶體地址總共兩個物件