JVM啓動流程java
JVM是Java程序運行的環境,同時是一個操做系統的一個應用程序進程,所以它有本身的生命週期,也有本身的代碼和數據空間。 JVM工做原理和特色主要是指操做系統裝入JVM,是經過jdk中Java.exe來完成,經過下面4步來完成JVM環境。算法
1.建立JVM裝載環境和配置 JVM裝入環境,JVM提供的方式是操做系統的動態鏈接文件數組
3.初始化JVM.dll並掛界到JNIENV(JNI調用接口)實例 這樣就能夠在Java中調用JVM的函數了.調用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法得到JNIEnv結構的實例.安全
4.調用JNIEnv實例裝載並處理class類。markdown
JVM基本結構架構
JVM體系主要是兩個JVM的內部體系結構分爲三個子系統和兩大組件,分別是:類裝載器(ClassLoader)子系統、執行引擎子系統和GC子系統,組件是內存運行數據區域和本地接口。函數
· 方法區(永久代) 方法區存儲了每一個類的信息,好比類型的常量池、字段,方法信息、方法字節碼。全部線程共享同一個方法區,所以訪問方法區數據的和動態連接的進程必須線程安全。若是兩個線程試圖訪問一個還未加載的類的字段或方法,必須只加載一次,並且兩個線程必須等它加載完畢才能繼續執行。spa
(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棧是線程私有的內存區域,其中存儲的是棧幀。,每一次方法調用建立一個幀,並壓棧,調用完畢出棧。下面是內存的線程公有私有示意圖:
通常由三部分組成:局部變量表、操做數據棧和幀數據區 局部變量表:能夠存放的數據有8種基本數據類型(boolean,byte,char,short,int,float,long,double),對象引用和returnAddress類型。其中long和double由於是64位,會佔用兩個局部變量的空間。
操做數棧:主要保存計算過程的中間結果,同時做爲計算過程當中的變量臨時的存儲空間。 下圖是一個兩數相加的操做數棧的過程:
棧上分配 小對象(通常幾十個bytes),在沒有逃逸的狀況下,能夠直接分配在棧上 直接分配在棧上,能夠自動回收,減輕GC壓力 大對象或者逃逸對象沒法棧上分配
· 本地方法棧(Native Method Stack) 本地方法棧也是線程私有的內存區域,與java棧比較類似,不一樣之處在於該區域主要是保存Native方法相關的數據。Native方法是非Java語言編寫的方法。 與虛擬機棧同樣,本地方法棧區域也會拋出StackOverflowError和OutOfMemoryError異常。
專一於Java架構師技術分享,撩我免費送Java全套架構師晉級資料 (Java架構師交流企Q鵝裙*/:445-820-*908 )