国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java內(nèi)存管理機(jī)制

2019-11-06 07:57:26
字體:
供稿:網(wǎng)友

一:運行時的數(shù)據(jù)區(qū)域                                                          

java虛擬機(jī)在執(zhí)行java程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。這些區(qū)域都有各自的用途,以及創(chuàng)建和銷毀的時間,有的區(qū)域隨著虛擬機(jī)進(jìn)程的啟動和存在,有些區(qū)域則依賴用戶線程的啟動和結(jié)束而建立和銷毀。

 

 

1.1:程序計數(shù)器

程序計數(shù)器(PRogram Counter Register)是一塊較小的內(nèi)存空間,它可以看做是當(dāng)前程序執(zhí)行的字節(jié)碼的行號指示器。

由于Java虛擬機(jī)的多線程是通過線程輪流切換并分配處理器執(zhí)行時間的方法來實現(xiàn)的,在任何一個確定的時間,一個處理器都只會執(zhí)行一條線程中的指令。所以為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個獨立的程序計數(shù)器,各線程之間計數(shù)器互不影響。

1.2:Java虛擬機(jī)棧

Java虛擬機(jī)棧也是線程私有的,它的生命周期與線程相同。虛擬機(jī)棧描述的是java方法執(zhí)行的內(nèi)存模式:每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。每一個方法從調(diào)用直至執(zhí)行完成的過程,就對應(yīng)著一個棧幀在虛擬機(jī)棧中入棧到出棧的過程。

1.3:本地方法棧

本地方法棧與虛擬機(jī)棧發(fā)揮的作用是非常相似的,他們之間的區(qū)別不過是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為了虛擬機(jī)使用到Native方法服務(wù)。

1.4:Java堆

對于大多數(shù)應(yīng)用來說,Java堆是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時創(chuàng)建。次內(nèi)存區(qū)域的唯一目的就是存放對象實類,幾乎所有的對象實例都在這里分配內(nèi)存。這一點在Java虛擬機(jī)規(guī)范中的描述是:所有的對象實例以及數(shù)組都要在堆上分配。但隨著JIT編譯器的發(fā)展,所有的對象都分配在堆上也漸漸變得不那么絕對了。

Java堆是垃圾收集器管理的主要區(qū)域,因此很多時候也被稱作“GC堆”(Garbage Collection Heap)。從內(nèi)存回收的角度看,由于現(xiàn)在收集器基本都采用分代收集算法,所以Java堆中還可以細(xì)分為:新生代和老年代。從內(nèi)存分配的角度來看,線程共享的Java堆中可能劃分出多個線程私有的分配緩沖區(qū),其實這樣主要是為了更好的回收內(nèi)存,或者更快的分配內(nèi)存。

1.5:方法區(qū)

方法區(qū),其實又可以叫做靜態(tài)區(qū)。與Java堆一樣,是各個線程所共享的內(nèi)存區(qū)域,它用于存儲已近被虛擬機(jī)加載的信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。

1.6:運行時常量池

運行時常量池是方法區(qū)的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運行時常量池中存放。

因為是方法區(qū)的一部分,所以受到方法區(qū)內(nèi)存的限制,當(dāng)常量池?zé)o法再申請到內(nèi)存是會拋出OutOfMemoryError異常。

1.7:直接內(nèi)存

其實直接內(nèi)存并不屬于虛擬機(jī)運行時數(shù)據(jù)區(qū)的一部分,也不是Java虛擬機(jī)內(nèi)存區(qū)域,但這部分內(nèi)存也在被頻繁的使用,而且當(dāng)內(nèi)存不足的時候,也會拋出OutOfMemoryError異常。NIO類,它可以使用Native函數(shù)庫直接分配堆外內(nèi)存,然而通過一個存儲在Java中的DirectByteBuffer對象作為這塊內(nèi)存的引用進(jìn)行操作。本機(jī)直接內(nèi)存的分配不會受到Java堆大小的限制,但是作為內(nèi)存,還是會受到本機(jī)總內(nèi)存大小以及處理器尋址空間的限制。

 

二:HotSpot虛擬機(jī)對象

2.1:對象的 創(chuàng)建

Java是一門面向?qū)ο蟮木幊陶Z言,在Java程序運行過程中無時無刻都在創(chuàng)建對象。相比大家都知道,當(dāng)用到關(guān)鍵字new時候,即實例化一個對象。當(dāng)虛擬機(jī)遇到一條new指令的時候,首先會去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已經(jīng)被加載、解析、和初始化過。如果沒用,那必須先執(zhí)行相應(yīng)的類加載過程。在類加載檢查通過后,接下來虛擬機(jī)講為新生對象分配內(nèi)存,即從java堆中劃分一個確定大小的出來。在內(nèi)存分配完后,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為零值。接下來。虛擬機(jī)要對對象進(jìn)行必要的設(shè)置。在這些工作完成后,從虛擬機(jī)來看,一個新的對象已近生成,但從java程序視角來看,對象創(chuàng)建才剛剛開始----<init>方法還沒有執(zhí)行,所有字段都還為零。所以,一般來說,執(zhí)行new指令之后,會接著執(zhí)行init方法,這樣一個真正的對象才算生成。

2.2:對象的內(nèi)存布局

在HotSpot虛擬機(jī)中,對象在內(nèi)存中存儲的布局可以分為三塊區(qū)域:對象頭,實例數(shù)據(jù)和對齊填充。

2.3:對象的訪問位置:

建立對象是為了使用對象,Java程序需要通過棧上的reference數(shù)據(jù)來操作堆上的具體對象。由于reference類型在Java虛擬機(jī)規(guī)范中規(guī)定了一個指向?qū)ο蟮囊茫]有定義這個引用應(yīng)該通過何種方式去定位、訪問堆中的對象的具體位置,所以對象的訪問方式也是取決于虛擬機(jī)實現(xiàn)而定。目前主流的訪問方式使用句柄和直接指針兩種。

句柄:Java堆中會劃出一塊內(nèi)存作為句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數(shù)據(jù)與類型數(shù)據(jù)各自的具體地址信息。

直接指針:如果使用這種方式的話,那么Java堆對象的布局中就必須考慮如何放置訪問類型數(shù)據(jù)的相關(guān)信息,reference中存儲的就是對象的地址。

兩種對象訪問各有優(yōu)勢。

 

 注:本文章參考《深入理解Java虛擬機(jī)》

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 高雄县| 石景山区| 克拉玛依市| 内黄县| 海宁市| 互助| 成安县| 包头市| 横峰县| 武乡县| 临桂县| 金秀| 高平市| 南木林县| 涡阳县| 余姚市| 车险| 泸溪县| 武穴市| 姜堰市| 大化| 陇川县| 蒲城县| 东至县| 上虞市| 利津县| 宁陕县| 沧源| 白城市| 广水市| 边坝县| 绥滨县| 汪清县| 余干县| 公主岭市| 容城县| 云和县| 南和县| 柳河县| 汤阴县| 浦县|