Java架構師JVM啟動流程和內存結構,程序員必看!

JVM是Java程序運行的環境,同時是一個操作系統的一個應用程序進程,因此它有自己的生命周期,也有自己的代碼和數據空間。

JVM工作原理和特點主要是指操作系統裝入JVM,是通過jdk中Java.exe來完成,通過下面4步來完成JVM環境。

1.創建JVM裝載環境和配置

JVM裝入環境,JVM提供的方式是操作系統的動態連接文件

2.裝載JVM.dll

通過第一步已經找到了JVM的路徑,Java通過LoadJavaVM來裝入JVM.dll文件.裝入工作很簡單就是調用Windows API函數:

LoadLibrary裝載JVM.dll動態連接庫.然后把JVM.dll中的導出函數JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs掛接到InvocationFunctions變量的CreateJavaVM和GetDefaultJavaVMInitArgs函數指針變量上。JVM.dll的裝載工作宣告完成。

3.初始化JVM.dll并掛界到JNIENV(JNI調用接口)實例

這樣就可以在Java中調用JVM的函數了.調用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法獲得JNIEnv結構的實例.

4.調用JNIEnv實例裝載并處理class類。

JVM基本結構

? ? ? ? JVM體系主要是兩個JVM的內部體系結構分為三個子系統和兩大組件,分別是:類裝載器(ClassLoader)子系統、執行引擎子系統和GC子系統,組件是內存運行數據區域和本地接口。

?

· 程序計數器(PC寄存器)

PC(Program Couneter)寄存器是每個線程私有的,Java虛擬機會為每個線程創建PC寄存器,在任意時刻,一個Java線程總是在執行一個方法,這個方法稱為當前方法,如果當前方法不是本地方法,PC寄存器總會執行當前正在被執行的指令,如果是本地方法,則PC寄存器值為Underfined。每執行一條指令 PC 都會自增,因此 PC 存儲了指向下一條要被執行的指令地址。JVM 用 PC 來跟蹤指令執行的位置,PC 將實際上是指向方法區(Method Area)的一個內存地址。

· 方法區(永久代)

方法區存儲了每個類的信息,比如類型的常量池、字段,方法信息、方法字節碼。所有線程共享同一個方法區,因此訪問方法區數據的和動態鏈接的進程必須線程安全。如果兩個線程試圖訪問一個還未加載的類的字段或方法,必須只加載一次,而且兩個線程必須等它加載完畢才能繼續執行。

(JDK1.7中,已經把放在永久代的字符串常量池移到堆中。JDK1.8撤銷永久代,引入元空間。元空間是直接存在內存中,不在java虛擬機中的,因此元空間依賴于內存大小。當然你也可以自定義元空間大小。)

· 方法區不需要連續的內存,可以選擇固定大小或者可擴展。并且還可以選擇不實現垃圾收集。相對而言,垃圾收集行為在這個區域是比較少出現的,但并非數據進入了方法區就如永久代的名字一樣“永久”存在了。這個區域的內存回收目標主要是針對常量池的回收和對類型的卸載,一般來說這個區域的回收“成績”比較難以令人滿意,尤其是類型的卸載,條件相當苛刻,但是這部分區域的回收確實是有必要的。當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError異常。

· 堆(Heap)

應用系統對象都保存在Java堆中,堆被用來在運行時分配類實例、數組。不能在棧上存儲數組和對象。因為棧幀被設計為創建以后無法調整大小。棧幀只存儲指向堆中對象或數組的引用。與局部變量數組(每個棧幀中的)中的原始類型和引用類型不同,對象總是存儲在堆上以便在方法結束時不會被移除。對象只能由垃圾回收器移除。所有線程共享Java堆。

簡述垃圾回收

為了支持分代垃圾回收機制,堆內存可以劃分為新生代和老年代兩個區域(默認新生代與老年代的空間大小為1:2)。新生代可以再劃分為Eden區、From Survivor區和To Survivor區(三者比例為8:1:1)。幾乎所有的新對象的創建都是在Eden區進行的。在垃圾回收(GC)過程中,Eden中的活躍對象會被轉移到Survivor區,當再到達一定的年齡(經歷過的Minor GC的次數,每經過一次新生代回收,如果對象存活則它的年齡就加1,對象達到一定的年齡后),會被轉移到老年代中。

· Java棧(Java Stack)

Java棧是線程私有的內存區域,其中存儲的是棧幀。,每一次方法調用創建一個幀,并壓棧,調用完畢出棧。下面是內存的線程公有私有示意圖:

如果方法methodOne方法調用了methodTwo,那么methodOne就會先入棧創建一個棧楨,接著methodTwo再入棧成為棧頂(假設沒有其他的方法執行),methodTwo執行完先出棧,接著methodOne執行完出棧。

一般由三部分組成:局部變量表、操作數據棧和幀數據區

局部變量表:可以存放的數據有8種基本數據類型(boolean,byte,char,short,int,float,long,double),對象引用和returnAddress類型。其中long和double因為是64位,會占用兩個局部變量的空間。

每一個塊就是一個棧,如圖是兩個棧

在Java虛擬機規范中,對這個區域規定了兩種異常狀況:如果線程請求的棧深度大于虛擬機所允許的深度(比如遞歸調用的y時候),將拋出StackOverflowError異常;如果虛擬機棧可以動態擴展(當前大部分的Java虛擬機都可動態擴展,只不過Java虛擬機規范中也允許固定長度的虛擬機棧),當擴展時無法申請到足夠的內存時會拋出OutOfMemoryError異常。

操作數棧:主要保存計算過程的中間結果,同時作為計算過程中的變量臨時的存儲空間。? 下圖是一個兩數相加的操作數棧的過程:

so?Bz#+??

幀數據區:除了局部變量表和操作數據棧以外,棧還需要一些數據來支持常量池的解析,這里幀數據區保存著訪問常量池的指針,方便計程序訪問常量池,另外當函數返回或出現異常時賣虛擬機子必須有一個異常處理表,方便發送異常的時候找到異常的代碼,因此異常處理表也是幀數據區的一部分。

棧上分配

? 小對象(一般幾十個bytes),在沒有逃逸的情況下,可以直接分配在棧上

直接分配在棧上,可以自動回收,減輕GC壓力

大對象或者逃逸對象無法棧上分配

· 本地方法棧(Native Method Stack)

本地方法棧也是線程私有的內存區域,與java棧比較相似,不同之處在于該區域主要是保存Native方法相關的數據。Native方法是非Java語言編寫的方法。

與虛擬機棧一樣,本地方法棧區域也會拋出StackOverflowError和OutOfMemoryError異常。

專注于Java架構師技術分享,撩我免費送Java全套架構師晉級資料

(Java架構師交流企Q鵝裙*/*:445*-*820*-*908 )

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內容

  • 內存溢出和內存泄漏的區別 內存溢出:out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,...
    Aimerwhy閱讀 753評論 0 1
  • 第二部分 自動內存管理機制 第二章 java內存異常與內存溢出異常 運行數據區域 程序計數器:當前線程所執行的字節...
    小明oh閱讀 1,197評論 0 2
  • 注1:以下所提及線程,無特定說明的均默認指代“Java虛擬機線程”。 注2:注意避免混淆Stack、Heap和Ja...
    亨小利霍閱讀 672評論 1 4
  • 婚姻的初始,所有人都說那是兩個人的事,所有的長輩親戚都說:“只要他們倆好,我們怎么著都行”,而事實并非如此。 當婚...
    玉生煙閱讀 181評論 0 1
  • 今年生日,終于實現了自己的小目標,滿心歡喜。懷著對職業的崇高理想,對孩子的無限向往,我來到這里。 現實卻給了我狠狠...
    沂南036張霞閱讀 312評論 0 2