久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Java虛擬機(jī)詳解02

 primivite_ 2017-09-19

 

主要內(nèi)容如下:

  • JVM啟動(dòng)流程
  • JVM基本結(jié)構(gòu)
  • 內(nèi)存模型
  • 編譯和解釋運(yùn)行的概念

 

一,、JVM啟動(dòng)流程:

587f1e97-d4ed-4d7f-89c6-dabe944fed12

JVM啟動(dòng)時(shí),,是由java命令/javaw命令來(lái)啟動(dòng)的。

二,、JVM基本結(jié)構(gòu):

JVM基本結(jié)構(gòu)圖:

16865f32-a87b-4fee-9aed-a793016cf2a7

《深入理解Java虛擬機(jī)(第二版)》中的描述是下面這個(gè)樣子的:

96698196-0f6b-4ef6-9a20-85dd35d75f27

 

Java中的內(nèi)存分配:

Java程序在運(yùn)行時(shí),,需要在內(nèi)存中的分配空間。為了提高運(yùn)算效率,,就對(duì)數(shù)據(jù)進(jìn)行了不同空間的劃分,,因?yàn)槊恳黄瑓^(qū)域都有特定的處理數(shù)據(jù)方式和內(nèi)存管理方式。

具體劃分為如下5個(gè)內(nèi)存空間:(非常重要)

  • :存放局部變量
  • :存放所有new出來(lái)的東西
  • 方法區(qū):被虛擬機(jī)加載的類(lèi)信息,、常量,、靜態(tài)常量等。
  • 程序計(jì)數(shù)器(和系統(tǒng)相關(guān))
  • 本地方法棧

1,、程序計(jì)數(shù)器:

每個(gè)線(xiàn)程擁有一個(gè)PC寄存器

在線(xiàn)程創(chuàng)建時(shí)創(chuàng)建

指向下一條指令的地址

執(zhí)行本地方法時(shí),,PC的值為undefined

2、方法區(qū): 

保存裝載的類(lèi)信息

  類(lèi)型的常量池

  字段,,方法信息

  方法字節(jié)碼

通常和永久區(qū)(Perm)關(guān)聯(lián)在一起

3,、堆內(nèi)存:

和程序開(kāi)發(fā)密切相關(guān)

應(yīng)用系統(tǒng)對(duì)象都保存在Java堆中

所有線(xiàn)程共享Java堆

對(duì)分代GC來(lái)說(shuō),堆也是分代的

GC管理的主要區(qū)域

現(xiàn)在的GC基本都采用分代收集算法,如果是分代的,,那么堆也是分代的,。如果堆是分代的,那堆空間應(yīng)該是下面這個(gè)樣子:

8d74ba35-9865-4434-8be5-73cec9e93295

上圖是堆的基本結(jié)構(gòu),,在之后的文章中再進(jìn)行詳解,。

4、棧內(nèi)存:

  • 線(xiàn)程私有,,生命周期和線(xiàn)程相同
  • 棧由一系列幀組成(因此Java棧也叫做幀棧)
  • 幀保存一個(gè)方法的局部變量,、操作數(shù)棧、常量池指針
  • 每一次方法調(diào)用創(chuàng)建一個(gè)幀,,并壓棧

解釋?zhuān)?/p>

Java虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型每個(gè)方法被調(diào)用的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀,,用于存儲(chǔ)局部變量表、操作棧,、動(dòng)態(tài)鏈接,、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完成的過(guò)程就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)中從入棧到出棧的過(guò)程,。

在Java虛擬機(jī)規(guī)范中,,對(duì)這個(gè)區(qū)域規(guī)定了兩種異常情況:

    (1)如果線(xiàn)程請(qǐng)求的棧深度太深,超出了虛擬機(jī)所允許的深度,,就會(huì)出現(xiàn)StackOverFlowError(比如無(wú)限遞歸,。因?yàn)槊恳粚訔颊加靡欢臻g,而 Xss 規(guī)定了棧的最大空間,,超出這個(gè)值就會(huì)報(bào)錯(cuò))

    (2)虛擬機(jī)??梢詣?dòng)態(tài)擴(kuò)展,如果擴(kuò)展到無(wú)法申請(qǐng)足夠的內(nèi)存空間,,會(huì)出現(xiàn)OOM

 

4.1  Java棧之局部變量表:包含參數(shù)和局部變量

    局部變量表存放了基本數(shù)據(jù)類(lèi)型,、對(duì)象引用和returnAddress類(lèi)型(指向一條字節(jié)碼指令的地址)。其中64位長(zhǎng)度的long和double類(lèi)型的數(shù)據(jù)會(huì)占用2個(gè)局部變量空間(slot),,其余數(shù)據(jù)類(lèi)型只占用1個(gè),。局部變量表所需的內(nèi)存空間在編譯期間完成分配。

例如,,我寫(xiě)出下面這段代碼:

復(fù)制代碼
 1 package test03;
 2 
 3 /**
 4  * Created by smyhvae on 2015/8/15.
 5  */
 6 public class StackDemo {
 7     
 8     //靜態(tài)方法
 9     public static int runStatic(int i, long l, float f, Object o, byte b) {
10         return 0;
11     }
12 
13     //實(shí)例方法
14     public int runInstance(char c, short s, boolean b) {
15         return 0;
16     }
17 
18 }
復(fù)制代碼

 

上方代碼中,,靜態(tài)方法有6個(gè)形參,實(shí)例方法有3個(gè)形參,。其對(duì)應(yīng)的局部變量表如下:

1272c229-ef70-4898-9ede-66828e6b84f7

上方表格中,,靜態(tài)方法和實(shí)例方法對(duì)應(yīng)的局部變量表基本類(lèi)似。但有以下區(qū)別:實(shí)例方法的表中,,第一個(gè)位置存放的是當(dāng)前對(duì)象的引用,。

 

4、2  Java棧之函數(shù)調(diào)用組成棧幀

方法每次被調(diào)用的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀例如下面這個(gè)方法

public static int runStatic(int i,long l,float  f,Object o ,byte b){
       return runStatic(i,l,f,o,b);
}

 

當(dāng)它每次被調(diào)用的時(shí)候,,都會(huì)創(chuàng)建一個(gè)幀,,方法調(diào)用結(jié)束后,幀出棧,。如下圖所示:

1244af96-c081-4059-98de-7881ec4c792e

 

4.3  Java棧之操作數(shù)棧

Java沒(méi)有寄存器,所有參數(shù)傳遞都是使用操作數(shù)棧

例如下面這段代碼:

    public static int add(int a,int b){
        int c=0;
        c=a+b;
        return c;
    }

 

壓棧的步驟如下:

  0:   iconst_0 // 0壓棧

  1:   istore_2 // 彈出int,,存放于局部變量2

  2:   iload_0  // 把局部變量0壓棧

  3:   iload_1 // 局部變量1壓棧

  4:   iadd      //彈出2個(gè)變量,,求和,結(jié)果壓棧

  5:   istore_2 //彈出結(jié)果,,放于局部變量2

  6:   iload_2  //局部變量2壓棧

  7:   ireturn   //返回

如果計(jì)算100+98的值,,那么操作數(shù)棧的變化如下圖所示:

35721707-fff7-4516-86a7-dda30320dc06

 

 

4.4  Java棧之棧上分配:

小對(duì)象(一般幾十個(gè)bytes),在沒(méi)有逃逸的情況下,,可以直接分配在棧上

直接分配在棧上,,可以自動(dòng)回收,減輕GC壓力

大對(duì)象或者逃逸對(duì)象無(wú)法棧上分配

棧,、堆,、方法區(qū)交互:

7efdd9ad-03a3-41e8-9635-36d5506a23f9f29029fe-8cef-47ea-b091-e3f19d6a9801

 

 

三、內(nèi)存模型:

每一個(gè)線(xiàn)程有一個(gè)工作內(nèi)存,。工作內(nèi)存和主存獨(dú)立,。工作內(nèi)存存放主存中變量的值的拷貝。

7883501b-7e5c-4064-af0d-438a118acbf6

當(dāng)數(shù)據(jù)從主內(nèi)存復(fù)制到工作存儲(chǔ)時(shí),,必須出現(xiàn)兩個(gè)動(dòng)作:第一,,由主內(nèi)存執(zhí)行的讀(read)操作;第二,,由工作內(nèi)存執(zhí)行的相應(yīng)的load操作,;當(dāng)數(shù)據(jù)從工作內(nèi)存拷貝到主內(nèi)存時(shí),也出現(xiàn)兩個(gè)操作:第一個(gè),,由工作內(nèi)存執(zhí)行的存儲(chǔ)(store)操作,;第二,由主內(nèi)存執(zhí)行的相應(yīng)的寫(xiě)(write)操作,。

每一個(gè)操作都是原子的,,即執(zhí)行期間不會(huì)被中斷

對(duì)于普通變量,一個(gè)線(xiàn)程中更新的值,,不能馬上反應(yīng)在其他變量中,。如果需要在其他線(xiàn)程中立即可見(jiàn),需要使用volatile關(guān)鍵字作為標(biāo)識(shí),。

d481032e-ed23-46c2-9c5c-5f34e3193ef9

1,、可見(jiàn)性:

  一個(gè)線(xiàn)程修改了變量,其他線(xiàn)程可以立即知道

保證可見(jiàn)性的方法:

volatile

synchronized (unlock之前,寫(xiě)變量值回主存)

final(一旦初始化完成,,其他線(xiàn)程就可見(jiàn))

2,、有序性:

  在本線(xiàn)程內(nèi),操作都是有序的

  在線(xiàn)程外觀察,,操作都是無(wú)序的,。(指令重排 或 主內(nèi)存同步延時(shí))

3、指令重排:

142d481b-f4a3-4c23-b56d-cf3ec5b63a2e

指令重排:破壞了線(xiàn)程間的有序性:

154748eb-cc14-48ee-b66f-cdcc26068cd1

 

 

指令重排:保證有序性的方法:

e0bcca41-a6e1-4a5c-b723-e0d721875acc

指令重排的基本原則:

程序順序原則:一個(gè)線(xiàn)程內(nèi)保證語(yǔ)義的串行性

volatile規(guī)則:volatile變量的寫(xiě),,先發(fā)生于讀

鎖規(guī)則:解鎖(unlock)必然發(fā)生在隨后的加鎖(lock)前

傳遞性:A先于B,,B先于C 那么A必然先于C

線(xiàn)程的start方法先于它的每一個(gè)動(dòng)作

線(xiàn)程的所有操作先于線(xiàn)程的終結(jié)(Thread.join())

線(xiàn)程的中斷(interrupt())先于被中斷線(xiàn)程的代碼

對(duì)象的構(gòu)造函數(shù)執(zhí)行結(jié)束先于finalize()方法

 

四、解釋運(yùn)行和編譯運(yùn)行的概念:

解釋運(yùn)行:

解釋執(zhí)行以解釋方式運(yùn)行字節(jié)碼

解釋執(zhí)行的意思是:讀一句執(zhí)行一句

編譯運(yùn)行(JIT):

將字節(jié)碼編譯成機(jī)器碼

直接執(zhí)行機(jī)器碼

運(yùn)行時(shí)編譯

編譯后性能有數(shù)量級(jí)的提升

編譯運(yùn)行的性能優(yōu)于解釋運(yùn)行,。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多