java 虛擬機(jī)(JVM)相關(guān)概念
- 作者:新網(wǎng)
- 來源:新網(wǎng)
- 瀏覽:100
- 2018-04-28 17:04:02
JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫,JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。
<
div> JVM是Java Virtual Machine(Java
虛擬機(jī))的縮寫,JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。
Java語言的一個(gè)非常重要的特點(diǎn)就是與平臺(tái)的無關(guān)性。而使用Java虛擬機(jī)是實(shí)現(xiàn)這一特點(diǎn)的關(guān)鍵。一般的高級(jí)語言如果要在不同的平臺(tái)上運(yùn)行,至少需要編譯成不同的目標(biāo)代碼。而引入Java語言虛擬機(jī)后,Java語言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯。Java語言使用Java虛擬機(jī)屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。Java虛擬機(jī)在執(zhí)行字節(jié)碼時(shí),把字節(jié)碼解釋成具體平臺(tái)上的機(jī)器指令執(zhí)行。這就是Java的能夠"一次編譯,到處運(yùn)行"的原因。
JVM是
java的核心和基礎(chǔ),在java編譯器和os平臺(tái)之間的虛擬處理器。它是一種基于下層的
操作系統(tǒng)和硬件平臺(tái)并利用軟件方法來實(shí)現(xiàn)的抽象的計(jì)算機(jī),可以在上面執(zhí)行java的字節(jié)碼程序。
Android的虛擬機(jī)是根據(jù)移動(dòng)設(shè)備的特點(diǎn)基于Java虛擬機(jī)(JVM)改進(jìn)而來,雖然沒有保留規(guī)范,但作為Java語言的使用者,了解一下JVM的規(guī)范還是有必要的。
VM在執(zhí)行Java程序時(shí),會(huì)把它管理的內(nèi)存劃分為若干個(gè)的區(qū)域,每個(gè)區(qū)域都有自己的用途和創(chuàng)建銷毀時(shí)間。如下圖所示,可以分為兩大部分,線程私有區(qū)和共享區(qū):
線程私有區(qū)
程序計(jì)數(shù)器。當(dāng)同時(shí)進(jìn)行的線程數(shù)超過CPU數(shù)或其內(nèi)核數(shù)時(shí),就要通過時(shí)間片輪詢分派CPU的時(shí)間資源,不免發(fā)生線程切換。這時(shí),每個(gè)線程就需要一個(gè)屬于自己的計(jì)數(shù)器來記錄下一條要運(yùn)行的指令。如果將是Java方法,則記錄執(zhí)行的字節(jié)碼地址;是本地方法,則計(jì)數(shù)器為空。
虛擬機(jī)棧,與線程同時(shí)創(chuàng)建。每個(gè)方法執(zhí)行時(shí)都會(huì)創(chuàng)建一個(gè)棧幀來存儲(chǔ)方法的信息,新調(diào)用的方法入棧,返回的出棧,所以棧的大小決定方法調(diào)用的可達(dá)深度。若需要的棧深度大于可用深度時(shí),則StackOverflowError;若棧進(jìn)行擴(kuò)展,但內(nèi)存不夠時(shí),OutOfMemoryError。
本地方法棧,與虛擬機(jī)棧作用相似。但它不是為Java方法服務(wù)的,而是本地方法(C語言)。由于規(guī)范對(duì)這塊沒有強(qiáng)制要求,不同虛擬機(jī)實(shí)現(xiàn)方法不同。
2.2.線程共享區(qū)
此區(qū)域是用來存儲(chǔ)被各線程共享的數(shù)據(jù)的。
方法區(qū),用于存放加載類的元數(shù)據(jù)信息,如常量、靜態(tài)變量和即時(shí)編譯器編譯后的代碼。若要分代,算是永久代,以前類大多“static”的,很少被卸載或收集,現(xiàn)回收廢棄常量和無用的類。其中運(yùn)行時(shí)常量池存放編譯生成的各種常量。
堆,存放對(duì)象實(shí)例和數(shù)組,是垃圾回收的主要區(qū)域,分為新生代和老年代。剛創(chuàng)建的對(duì)象在新生代的Eden區(qū)中,經(jīng)過GC后進(jìn)入新生代的S0區(qū)中,再經(jīng)過GC進(jìn)入新生代的S1區(qū)中,15次GC后仍存在就進(jìn)入老年代。這是按照一種回收機(jī)制進(jìn)行劃分的,不是固定的。若堆的
空間不夠?qū)嵗峙洌瑒tOutOfMemoryError。
棧是運(yùn)行時(shí)單位,代表著邏輯,內(nèi)含基本數(shù)據(jù)類型和堆中對(duì)象引用,所在區(qū)域連續(xù),沒有碎片;堆是存儲(chǔ)單位,代表著數(shù)據(jù),可被多個(gè)棧共享(包括成員中基本數(shù)據(jù)類型、引用和引用對(duì)象),所在區(qū)域不連續(xù),會(huì)有碎片。
JVM內(nèi)存結(jié)構(gòu)主要有三大塊:堆內(nèi)存、方法區(qū)和棧。堆內(nèi)存是JVM中最大的一塊由年輕代和老年代組成,而年輕代內(nèi)存又被分成三部分,Eden空間、FromSurvivor空間、To Survivor空間,默認(rèn)情況下年輕代按照8:1:1的比例來分配;
方法區(qū)存儲(chǔ)類信息、常量、靜態(tài)變量等數(shù)據(jù),是線程共享的區(qū)域,為與Java堆區(qū)分,方法區(qū)還有一個(gè)別名Non-Heap(非堆);棧又分為java虛擬機(jī)棧和本地方法棧主要用于方法的執(zhí)行。
就說到這里,大家可以留言交流。