日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
一文了解Java虛擬機(jī)的重要組成

一文了解Java虛擬機(jī)的重要組成

作者:菜根譚 2018-09-11 15:01:22

云計(jì)算

虛擬化 JVM是JAVA平臺(tái)的重要組成之一,因涉及知識(shí)點(diǎn)太多,故從以下幾個(gè)方面對(duì)JVM進(jìn)行淺層面的介紹。

在濮陽(yáng)縣等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶提供做網(wǎng)站、網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需網(wǎng)站制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),營(yíng)銷(xiāo)型網(wǎng)站建設(shè),外貿(mào)網(wǎng)站制作,濮陽(yáng)縣網(wǎng)站建設(shè)費(fèi)用合理。

JVM是JAVA平臺(tái)的重要組成之一,因涉及知識(shí)點(diǎn)太多,故從以下幾個(gè)方面對(duì)JVM進(jìn)行淺層面的介紹,如果需要深入理解,推薦學(xué)習(xí)機(jī)械工業(yè)出版社的《深入理解JAVA虛擬機(jī)》。

一、JAVA內(nèi)存結(jié)構(gòu)

Java虛擬機(jī)規(guī)范中規(guī)定的JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)如下圖所示:

總體來(lái)說(shuō),分為線程共享部分(方法區(qū)、堆)和線程隔離區(qū)(虛擬機(jī)棧、本地方法棧和程序計(jì)數(shù)器)。

1.方法區(qū)

用于存儲(chǔ)已被虛擬機(jī)加載的類(lèi)信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。其中常量存儲(chǔ)于運(yùn)行時(shí)常量區(qū)中,運(yùn)行時(shí)常量區(qū)是區(qū)的一部分,用于存儲(chǔ)編譯期生成的字面量和符號(hào)引用。但運(yùn)行時(shí)常量區(qū)的內(nèi)容并不只是在編譯期間產(chǎn)生,通過(guò)String.intern()也可以實(shí)現(xiàn)在運(yùn)行時(shí)向常量區(qū)中添加內(nèi)容。

2.堆

是JVM中***的一塊內(nèi)存區(qū)域,該區(qū)域的目的只是用于存儲(chǔ)對(duì)象實(shí)例及數(shù)組。該區(qū)域也是GC的最主要區(qū)域。

3.虛擬機(jī)棧

每個(gè)線程方法在執(zhí)行時(shí)都會(huì)創(chuàng)建一個(gè)棧幀,包含局部變量表、返回地址、操作數(shù)棧等信息。每個(gè)方法的執(zhí)行與完成就對(duì)應(yīng)的棧幀的入棧與出棧過(guò)程 。局部變量表占用空間的大小在編譯期就確定了。

4.本地方法棧

與虛擬機(jī)棧類(lèi)似,不過(guò)其中執(zhí)行是本地方法。對(duì)于HotSpot虛擬機(jī)而言,本地方法棧和虛擬機(jī)棧是統(tǒng)一的。

5.程序計(jì)數(shù)器

是一個(gè)小的內(nèi)存空間,如果線程正在執(zhí)行的是一個(gè)java方法,則此內(nèi)存區(qū)域記錄正在執(zhí)行的虛擬機(jī)字節(jié)碼指令;如果線程正在執(zhí)行的是native方法,則計(jì)算器中的值為空。

二、JAVA垃圾回收機(jī)制

JAVA的垃圾回收主要涉及到確定對(duì)象是否存活、垃圾收集等算法,其中確定對(duì)象回收算法采用的是可達(dá)性分析算法,垃圾收集目前各JVM廠商廣泛采用的是分代收集算法。這里面主要描述下分代收集算法的過(guò)程。

分代收集算法的核心思想是將內(nèi)存區(qū)域按照對(duì)象的生存周期階段進(jìn)行劃分,其中將堆區(qū)劃分為新生代(young generation)和老年代(old generation)。將非堆區(qū)(一般指方法區(qū))劃分為持久代(permanent generation)。

1.新生代

新生代又可再分為Eden區(qū)和兩個(gè)Survivor區(qū)(兩個(gè)Survivor區(qū)的大小是一樣的,便于交換)。新生成的對(duì)象都會(huì)先在新生代的Eden區(qū)進(jìn)行保存。新生代的特點(diǎn)是每次垃圾回收都會(huì)有大量的內(nèi)存被回收,而且收集比較頻繁,所以新生代適合如下的收集算法:

首先,新生成的對(duì)象分配到Eden區(qū),如果eden區(qū)滿了,則將可達(dá)性的對(duì)象復(fù)制到survivor1區(qū),后清空eden區(qū)。

然后,如果survivor1區(qū)滿了,則將eden區(qū)與survivor1區(qū)的可達(dá)性對(duì)象復(fù)制到survivor2區(qū),后清空eden區(qū)和survivor1區(qū),清空完后將survivor2區(qū)與survivor1區(qū)交換,即保持survivor2是空的。

再次,如果survivor2區(qū)也滿了,則將eden區(qū)、survivor1區(qū)、survivor2區(qū)的可達(dá)性對(duì)象復(fù)制到老年代中,并清空新生代中。

***,如果老年代也滿了,就觸發(fā)full gc了。

2.老年代

老年代的內(nèi)存比新生代大的多,這個(gè)區(qū)域執(zhí)行垃圾回收的頻度不高。當(dāng)老年代滿時(shí),會(huì)觸發(fā)full gc。

3.持久代

持久代一般指方法區(qū),該區(qū)需要回收的有廢棄的常量和類(lèi)。對(duì)于常量可用可達(dá)性分析的方法進(jìn)行判斷回收,對(duì)于類(lèi)則需要同時(shí)滿足以下條件才會(huì)被回收:

首先,該類(lèi)的所有實(shí)例對(duì)象都已被回收;

其次,該類(lèi)的類(lèi)加載器也已被回收;

再次,該類(lèi)的Class方法沒(méi)有在任何地方被引用,即無(wú)法通過(guò)在任何地方通過(guò)反射訪問(wèn)到該類(lèi)的方法。

4.什么時(shí)候會(huì)解決垃圾回收?

綜上所述,當(dāng)eden滿時(shí),就會(huì)觸發(fā)scavenge gc,當(dāng)出現(xiàn)以下情況時(shí)會(huì)觸發(fā)full gc:

老年代已滿;

持久代已滿;

調(diào)用System.gc()方法;

三、JAVA類(lèi)加載過(guò)程

JVM類(lèi)加載過(guò)程具體裝載、驗(yàn)證、準(zhǔn)備、解析、初始化這五個(gè)部分。

1.裝載

在裝載過(guò)程中,需要完成以下事情:

1)通過(guò)類(lèi)的全限定名獲取類(lèi)的二進(jìn)制字節(jié)流;

2)將類(lèi)的二進(jìn)制字節(jié)流轉(zhuǎn)換為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu);

3)生成一個(gè)代表此類(lèi)的java.lang.Class對(duì)象,作為方法區(qū)這個(gè)類(lèi)的各種數(shù)據(jù)的訪問(wèn)入口。

2.驗(yàn)證

驗(yàn)證、解析和初始化又稱(chēng)為是連接階段,在驗(yàn)證驗(yàn)證主要是確保二進(jìn)制字節(jié)流符合JVM的規(guī)范,不會(huì)危害計(jì)算機(jī)的安全。具體驗(yàn)證階段需要做的事情如下:

1)文件格式驗(yàn)證,驗(yàn)證字節(jié)流是否符合Class文件格式規(guī)范;

2)元數(shù)據(jù)驗(yàn)證,對(duì)字節(jié)碼進(jìn)行語(yǔ)義驗(yàn)證,以保證其描述信息符合JAVA語(yǔ)言規(guī)范;

3)字節(jié)碼驗(yàn)證,通過(guò)數(shù)據(jù)流和控制流分析,確定程序語(yǔ)義是合法的、符合邏輯的;

4)符號(hào)引用驗(yàn)證,對(duì)常量池中的各種符號(hào)引用的信息進(jìn)行匹配性驗(yàn)證。

3.準(zhǔn)備

準(zhǔn)備的過(guò)程其實(shí)是分配內(nèi)存的過(guò)程。在這個(gè)階段有兩個(gè)容易產(chǎn)生混淆的概念:一是此階段分配內(nèi)存的只是類(lèi)變量(static變量),不包含實(shí)例變量,實(shí)例變量的內(nèi)存分配是在對(duì)象實(shí)例化時(shí)隨對(duì)象一起分配在堆中;二是該階段分配內(nèi)存中保存的值只是數(shù)據(jù)類(lèi)型的零值,具體值需要在初始化階段進(jìn)行賦值。也有特殊情況,就是對(duì)于靜態(tài)常量(final修飾)會(huì)在準(zhǔn)備階段將值賦值為真實(shí)值。

4.解析

解析階段就是將常量池內(nèi)折符號(hào)引用轉(zhuǎn)換為直接引用的過(guò)程,具體包括類(lèi)和接口的解析、字段的解析、方法的解析、接口方法和解析。

5.初始化

初始化階段其實(shí)就是執(zhí)行類(lèi)構(gòu)造函數(shù)(clinit)的階段。對(duì)于clinit()需要說(shuō)明以下幾點(diǎn):

1)clinit()中的程序是自動(dòng)收集類(lèi)中static變量及static塊產(chǎn)生的,執(zhí)行順序與代碼中的順序一致。靜態(tài)語(yǔ)句塊中只能訪問(wèn)在其之前聲明的static變量,在其之后聲明的static變量只能賦值,不能訪問(wèn)。

2)執(zhí)行clinit()方法前,JVM會(huì)自動(dòng)調(diào)用父類(lèi)的clinit()方法;

3)虛擬機(jī)會(huì)保證一個(gè)類(lèi)的clinit()在多線程環(huán)境中,自動(dòng)加鎖、同步。

四、JVM的類(lèi)加載器

JVM的類(lèi)加載是通過(guò)類(lèi)加載器實(shí)現(xiàn)的,常用的類(lèi)加載器包括下面三種:

1.啟動(dòng)類(lèi)加載器(bootstrap classloader):加載{JDK_HOME}/lib下的類(lèi)

2.擴(kuò)展類(lèi)加載器(extension classloader):加載{JDK_HOME}/lib/ext下的類(lèi)

3.應(yīng)用程序類(lèi)加載器(application classloader):加載classpath指定的類(lèi)

對(duì)于不同類(lèi)加載器以及他們之間的協(xié)作可以參考下面的雙親委派模型。

雙親委派模型的工作過(guò)程是:如果一個(gè)類(lèi)加載器收到了類(lèi)的加載請(qǐng)求,會(huì)首先把請(qǐng)求委派給自己的父類(lèi),每個(gè)層次的類(lèi)加載器都會(huì)如此,因?yàn)樗械募虞d請(qǐng)求最終都會(huì)發(fā)送到bootstarp加載器中,只有當(dāng)父加載器確實(shí)無(wú)法自己完成加載請(qǐng)求時(shí),子加載器才會(huì)嘗試自己加載。

雙親委派模型使得JAVA類(lèi)能夠按層次進(jìn)行加載,不會(huì)造成混亂。

五、JVM的相關(guān)工具

JDK中有很多強(qiáng)大的監(jiān)控工具,可以直接在命令行運(yùn)行。這對(duì)于在生產(chǎn)環(huán)境進(jìn)行監(jiān)控是非常有用的。例如SUN JDK中就包含了以下監(jiān)控和故障處理工具。

jps: jvm process status tool,顯示指定系統(tǒng)內(nèi)所有的hotspot虛擬機(jī)進(jìn)程

jstat: jvm statistics monitoring tool,用于收集hotspot虛擬機(jī)各方面的運(yùn)行數(shù)據(jù)

jinfo: configuration info for java,顯示虛擬機(jī)配置信息

jmap: memory map for java,生成虛擬機(jī)的內(nèi)存轉(zhuǎn)儲(chǔ)快照(heapdump文件)

jhat: jvm heap dump browser,用于分析heapmap文件,它會(huì)建立一個(gè)http/html服務(wù)器,讓用戶可以在瀏覽器上查看分析結(jié)果

jstack: stack trace for java ,顯示虛擬機(jī)的線程快照


網(wǎng)站標(biāo)題:一文了解Java虛擬機(jī)的重要組成
本文鏈接:http://www.5511xx.com/article/cdgpijh.html