JVM 內存布局

經典JVM內存布局

Heap(堆區(qū))

Heap 是 OOM 主要發(fā)源地。堆分為兩大塊:新生代老年代。對象產生之初在新生代,步入暮年時進入老年代,但是老年代也接受新生代無法容納的超大對象
新生代 = 1Eden + 2 Survivor區(qū)。絕大部分對象在 Eden 區(qū)生成,當Eden區(qū)填滿時,觸發(fā) Young Garbage Collection,即 YGC。垃圾回收時在Eden區(qū)實現(xiàn)清除策略,沒有被引用的對象直接回收,依然存活送至 Survivor 區(qū)。Survivor 區(qū)分為 S0S1兩塊空間。每次 YGC 的時候將存活的對象復制到未使用的空間,然后將當前正在使用的空間完全清除,交換兩塊空間使用狀態(tài)。如果 YGC 要移送的對象大于 Survivor 區(qū)容量的上限,則直接移交老年代。每個對象都有一個計數(shù)器,每次 YGC 時 +1,當其打到一定閾值(默認 15)時晉升老年代。

Metaspace

在 JDK8版本中,元空間的前身 Perm區(qū)(永久代)已經淘汰。
區(qū)別于永久代,元空間在本地內存中分配。在 JDK8中,Perm 里的所有內容中字符串常量移至堆內存,其他內容包括類元信息、字段、靜態(tài)屬性、方法、常量等移至元空間內。

JVM Stack(虛擬機棧)

JVM 中虛擬機棧是描述 java 方法執(zhí)行的內存區(qū)域,他是線程私有的。棧中的元素用于支持虛擬機進行方法調用,每個方法從開始調用到執(zhí)行完成的過程,就是棧幀從入棧到出棧的過程。在活動線程中,只有位于棧頂?shù)膸攀怯行У模Q為當前棧幀。正在執(zhí)行的方法稱為當前方法,棧幀是方法運行的基本結構。所有指令只能針對當前棧幀進行操作。而 StackOverflowError 表示請求棧溢出,導致內存耗盡,通常出現(xiàn)在遞歸方法中。

局部變量表

局部變量表是存放方法參數(shù)和變量的區(qū)域。相對于類屬性變量的準備階段和初始化階段來說,局部變量沒有準備階段,必須顯示初始化。如果是非靜態(tài)方法,則在 index[0]位置上存儲的是方法所屬對象的實例引用,隨后存儲的是參數(shù)和局部變量。

操作棧

操作棧是一個初始狀態(tài)為空的桶式結構棧。JVM 的執(zhí)行引擎是基于的執(zhí)行引擎,這個棧指的就是操作棧

動態(tài)連接

每個棧幀中包含一個在常量池中對當前方法的引用,目的是支持方法調用過程的動態(tài)連接。

方法返回地址

方法執(zhí)行時有兩種退出情況:第一,正常退出(正常執(zhí)行到任何方法返回的返回字節(jié)碼指令,如 RETURN\IRETURN\ARETURN);第二,異常退出。不論何種退出都將返回至方法當前被調用的位置。
退出可能有三種方式:

  • 返回值壓入上層調用棧幀
  • 異常信息拋給能夠處理的棧幀
  • PC計數(shù)器指向方法調用后的下一條指令

Native Method Stacks(本地方法棧)

Native Method Stacks(本地方法棧)在 JVM 內存布局中,也是線程對象私有的。
虛擬機棧主,本地方法棧主。本地方法棧為 Native方法服務。本地方法可以通過JNI 來訪問虛擬機運行時的數(shù)據(jù)區(qū),甚至可以調用寄存器,具有 JVM 相同能力與權限。

Program Counter Register(程序計數(shù)器)

在Program Counter Register(程序計數(shù)器)中,程序計數(shù)器用來存放執(zhí)行指令的偏移量行號指示器等,線程執(zhí)行或恢復都要依賴程序計數(shù)器。程序計數(shù)器在各個線程之間互不影響,此區(qū)域也不會發(fā)生內存溢出異常。

最后,從線程共享角度來看,元空間所有線程共享的,而虛擬機棧本地方法棧程序計數(shù)器線程內部私有的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • JVM虛擬機內存結構,以及它們的作用 線程私有:棧區(qū),本地方法棧,pc指針線程共有:方法區(qū),堆區(qū) JAVA的JVM...
    Fitz_Lee閱讀 401評論 0 0
  • JVM在執(zhí)行 Java 程序的過程中會把它管理的內存劃分成若干個不同的數(shù)據(jù)區(qū)域。 這些組成部分一些事線程私有的,其...
    哦00閱讀 211評論 0 0
  • JVM架構 當一個程序啟動之前,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,698評論 0 7
  • 內存溢出和內存泄漏的區(qū)別 內存溢出:out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,...
    Aimerwhy閱讀 755評論 0 1
  • 原文閱讀 前言 這段時間懈怠了,罪過! 最近看到有同事也開始用上了微信公眾號寫博客了,挺好的~給他們點贊,這博客我...
    碼農戲碼閱讀 6,012評論 2 31