最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入探討Java內(nèi)存區(qū)域

 更新時(shí)間:2015年07月31日 10:48:42   投稿:lijiao  
本篇文章對(duì)Java內(nèi)存區(qū)域的使用進(jìn)行了詳細(xì)的介紹,內(nèi)容很全面,需要的朋友可以參考下

一、概述
Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干不同的數(shù)據(jù)區(qū)域,這些區(qū)域都有各自的用途以及創(chuàng)建和銷毀的時(shí)間。Java虛擬機(jī)所管理的內(nèi)存將會(huì)包括以下幾個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)域,如下圖所示:

下面就每一個(gè)區(qū)域進(jìn)行闡述。

二、運(yùn)行時(shí)數(shù)據(jù)區(qū)域
程序計(jì)數(shù)器

程序計(jì)數(shù)器,可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。在虛擬機(jī)的概念模型里,字節(jié)碼解釋器工作就是通過(guò)改變程序計(jì)數(shù)器的值來(lái)選擇下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都要依賴這個(gè)計(jì)數(shù)器來(lái)完成。

多線程中,為了讓線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器,各條線程之間互不影響、獨(dú)立存儲(chǔ),因此這塊內(nèi)存是 線程私有 的。

當(dāng)線程正在執(zhí)行的是一個(gè)Java方法,這個(gè)計(jì)數(shù)器記錄的是在正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址;當(dāng)執(zhí)行的是Native方法,這個(gè)計(jì)數(shù)器值為空。

此內(nèi)存區(qū)域是唯一一個(gè)沒(méi)有規(guī)定任何OutOfMemoryError情況的區(qū)域 。

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

局部變量表中存放了編譯器可知的各種基本數(shù)據(jù)類型(boolean、byte、char、short、int、float、long、double)、對(duì)象引用和returnAddress類型(指向了一條字節(jié)碼指令的地址)。

如果擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存,就會(huì)拋出OutOfMemoryError異常。

本地方法棧
本地方法棧與虛擬機(jī)的作用相似,不同之處在于虛擬機(jī)棧為虛擬機(jī)執(zhí)行的Java方法服務(wù),而本地方法棧則為虛擬機(jī)使用到的Native方法服務(wù)。有的虛擬機(jī)直接把本地方法棧和虛擬機(jī)棧合二為一。

會(huì)拋出stackOverflowError和OutOfMemoryError異常。

Java堆

Java堆是所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例 。

Java堆是垃圾收集器管理的主要區(qū)域。由于現(xiàn)在收集器基本采用分代回收算法,所以Java堆還可細(xì)分為:新生代和老年代。從內(nèi)存分配的角度來(lái)看,線程共享的Java堆中可能劃分出多個(gè)線程私有的分配緩沖區(qū)(TLAB)。

Java堆可以處于物理上不連續(xù)的內(nèi)存空間,只要邏輯上連續(xù)的即可。在實(shí)現(xiàn)上,既可以實(shí)現(xiàn)固定大小的,也可以是擴(kuò)展的。

如果堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆也無(wú)法完成擴(kuò)展時(shí),將會(huì)拋出OutOfMemoryError異常。

方法區(qū)

方法區(qū)是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù) 。

相對(duì)而言,垃圾收集行為在這個(gè)區(qū)域比較少出現(xiàn),但并非數(shù)據(jù)進(jìn)了方法區(qū)就永久的存在了,這個(gè)區(qū)域的內(nèi)存回收目標(biāo)主要是針對(duì)常量池的回收和對(duì)類型的卸載,

當(dāng)方法區(qū)無(wú)法滿足內(nèi)存分配需要時(shí),將拋出OutOfMemoryError異常。

運(yùn)行時(shí)常量池:

是方法區(qū)的一部分,它用于存放編譯期生成的各種字面量和符號(hào)引用。

直接內(nèi)存

直接內(nèi)存不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分,在NIO類中引入一種基于通道與緩沖區(qū)的IO方式,它可以使用Native函數(shù)庫(kù)直接分配堆外內(nèi)存,然后通過(guò)一個(gè)存儲(chǔ)在Java堆中的DirectByteBuffer對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作。

直接內(nèi)存的分配不會(huì)受到Java堆大小的限制,但是會(huì)受到本機(jī)內(nèi)存大小的限制,所有也可能會(huì)拋OutOfMemoryError異常。

三、對(duì)象的創(chuàng)建、布局和訪問(wèn)過(guò)程
對(duì)象的創(chuàng)建

創(chuàng)建一個(gè)對(duì)象通常是需要new關(guān)鍵字,當(dāng)虛擬機(jī)遇到一條new指令時(shí),首先檢查這個(gè)指令的參數(shù)是否在常量池中定位到一個(gè)類的符號(hào)引用,并且檢查這個(gè)符號(hào)引用代表的類是否已被加載、解析和初始化過(guò)。如果那么執(zhí)行相應(yīng)的類加載過(guò)程。

類加載檢查通過(guò)后,虛擬機(jī)將為新生對(duì)象分配內(nèi)存。為對(duì)象分配空間的任務(wù)等同于把一塊確定大小的內(nèi)存從Java堆中劃分出來(lái)。分配的方式有兩種: 一種叫 指針碰撞 ,假設(shè)Java堆中內(nèi)存是絕對(duì)規(guī)整的,用過(guò)的和空閑的內(nèi)存各在一邊,中間放著一個(gè)指針作為分界點(diǎn)的指示器,分配內(nèi)存就是把那個(gè)指針向空閑空間的那邊挪動(dòng)一段與對(duì)象大小相等的距離。 另一種叫 空閑列表 :如果Java堆中的內(nèi)存不是規(guī)整的,虛擬機(jī)就需要維護(hù)一個(gè)列表,記錄哪個(gè)內(nèi)存塊是可用的,在分配的時(shí)候從列表中找到一塊足夠大的空間劃分給對(duì)象實(shí)例,并更新列表上的記錄。 采用哪種分配方式是由Java堆是否規(guī)整決定的,而Java堆是否規(guī)整是由所采用的垃圾收集器是否帶有壓縮整理功能決定的。 另 外一個(gè)需要考慮的問(wèn)題就是對(duì)象創(chuàng)建時(shí)的線程安全問(wèn)題,有兩種解決方案:一是對(duì)分配內(nèi)存空間的動(dòng)作進(jìn)行同步處理;另一種是吧內(nèi)存分配的動(dòng)作按照線程劃分在不 同的空間之中進(jìn)行,即每個(gè)線程在Java堆中預(yù)先分配一小塊內(nèi)存(TLAB),哪個(gè)線程要分配內(nèi)存就在哪個(gè)線程的TLAB上分配,只有TLAB用完并分配 新的TLAB時(shí)才需要同步鎖定。

內(nèi)存分配完成后,虛擬機(jī)需要將分配到的內(nèi)存空間初始化為零值。這一步操作保證了對(duì)象的實(shí)例字段在Java代碼中可以不賦初始值就可以直接使用。

接下來(lái)虛擬機(jī)要對(duì)對(duì)象進(jìn)行必要的設(shè)置,例如這個(gè)對(duì)象是哪個(gè)類的實(shí)例、如何才能找到類的元數(shù)據(jù)信息等,這些信息存放在對(duì)象的對(duì)象頭中。

上面的工作都完成以后,從虛擬機(jī)的角度來(lái)看一個(gè)新的對(duì)象已經(jīng)產(chǎn)生了。但是從Java程序的角度,還需要執(zhí)行init方法,把對(duì)象按照程序員的意愿進(jìn)行初始化,這樣一個(gè)真正可用的對(duì)象才算完全產(chǎn)生出來(lái)。

對(duì)象的內(nèi)存布局
在HotSpot虛擬機(jī)中,對(duì)象在內(nèi)存中存儲(chǔ)的布局可分為三個(gè)部分: 對(duì)象頭、實(shí)例數(shù)據(jù)和對(duì)齊填充。

對(duì)象頭包括兩個(gè)部分:第一部分用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),如哈希碼、GC分代年齡、線程所持有的鎖等。官方稱之為“Mark Word”。第二個(gè)部分為是類型指針,即對(duì)象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過(guò)這個(gè)指針來(lái)確定這個(gè)對(duì)象是哪個(gè)類的實(shí)例。

實(shí)例數(shù)據(jù)是對(duì)象真正存儲(chǔ)的有效信息,也是程序代碼中所定義的各種類型的字段內(nèi)容。

對(duì)齊填充并不是必然存在的,僅僅起著占位符的作用。、Hotpot VM要求對(duì)象起始地址必須是8字節(jié)的整數(shù)倍,對(duì)象頭部分正好是8字節(jié)的倍數(shù),所以當(dāng)實(shí)例數(shù)據(jù)部分沒(méi)有對(duì)齊時(shí),需要通過(guò)對(duì)齊填充來(lái)對(duì)齊。

對(duì)象的訪問(wèn)定位
Java程序通過(guò)棧上的reference數(shù)據(jù)來(lái)操作堆上的具體對(duì)象。主要的訪問(wèn)方式有使用句柄和直接指針兩種:

句柄:Java堆將會(huì)劃出一塊內(nèi)存來(lái)作為句柄池,引用中存儲(chǔ)的就是對(duì)象的句柄地址,而句柄中包含了對(duì)象實(shí)例數(shù)據(jù)與類型數(shù)據(jù)各自的具體地址信息 。如圖所示:

直接指針:Java堆對(duì)象的布局要考慮如何放置訪問(wèn)類型數(shù)據(jù)的相關(guān)信息,引用中存儲(chǔ)的就是對(duì)象地址 。如圖所示:

兩個(gè)方式各有優(yōu)點(diǎn),使用句柄最大的好處是引用中存儲(chǔ)的是穩(wěn)定的句柄地址,對(duì)象被移動(dòng)時(shí)只會(huì)改變句柄中實(shí)例的地址,引用不需要修改、使用直接指針訪問(wèn)的好處是速度更快,它節(jié)省了一次指針定位的時(shí)間開(kāi)銷。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • Java設(shè)計(jì)模式之策略模式詳解和示例

    Java設(shè)計(jì)模式之策略模式詳解和示例

    這篇文章主要介紹了Java設(shè)計(jì)模式之策略模式詳解和示例,策略模式就是一種行為可能會(huì)因?yàn)椴煌倪壿嬙斐啥鄠€(gè)算法,比如人吃飯,美國(guó)人吃飯用刀叉,中國(guó)吃飯用筷子,都是吃飯的行為但是使用的工具(算法)不一樣,需要的朋友可以參考下
    2024-01-01
  • Java編程中避免equals方法的隱藏陷阱介紹

    Java編程中避免equals方法的隱藏陷阱介紹

    這篇文章主要介紹了Java編程中避免equals方法的隱藏陷阱介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Dubbo架構(gòu)整體設(shè)計(jì)詳解

    Dubbo架構(gòu)整體設(shè)計(jì)詳解

    Dubbo是一款高性能、輕量級(jí)的開(kāi)源Java RPC框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn),本文將從 Dubbo 整體架構(gòu)的視角出發(fā),帶你從全局俯瞰 Dubbo 的架構(gòu)設(shè)計(jì),感興趣的同學(xué)可以參考一下
    2023-04-04
  • 基于Java文件輸入輸出流實(shí)現(xiàn)文件上傳下載功能

    基于Java文件輸入輸出流實(shí)現(xiàn)文件上傳下載功能

    這篇文章主要為大家詳細(xì)介紹了基于Java文件輸入輸出流實(shí)現(xiàn)文件上傳下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 圖文詳解JAVA實(shí)現(xiàn)快速排序

    圖文詳解JAVA實(shí)現(xiàn)快速排序

    這篇文章主要給大家介紹了關(guān)于JAVA實(shí)現(xiàn)快速排序的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • java實(shí)現(xiàn)簡(jiǎn)單的客戶信息管理系統(tǒng)

    java實(shí)現(xiàn)簡(jiǎn)單的客戶信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單的客戶信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Java?@Accessors注解圖文詳解

    Java?@Accessors注解圖文詳解

    @Accessors用于改變@Data生成的getter和setter方法的生成結(jié)果,下面這篇文章主要給大家介紹了關(guān)于Java?@Accessors注解的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 基于Jmeter生成測(cè)試報(bào)告過(guò)程圖解

    基于Jmeter生成測(cè)試報(bào)告過(guò)程圖解

    這篇文章主要介紹了基于Jmeter生成測(cè)試報(bào)告過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot整合logback的示例代碼

    SpringBoot整合logback的示例代碼

    Logback是由log4j創(chuàng)始人設(shè)計(jì)的又一個(gè)開(kāi)源日志組件,logback分為三個(gè)模塊,在文章開(kāi)頭給大家介紹的很明確,接下來(lái)通過(guò)本文重點(diǎn)介紹下SpringBoot整合logback的方法,需要的朋友可以參考下
    2022-04-04
  • SpringBoot?中使用?Validation?校驗(yàn)參數(shù)的方法詳解

    SpringBoot?中使用?Validation?校驗(yàn)參數(shù)的方法詳解

    Validation?是用于檢查程序代碼中參數(shù)的有效性的框架,作為?Spring?框架中的一個(gè)參數(shù)校驗(yàn)工具,集成在?spring-context?包中,這篇文章主要介紹了SpringBoot?中使用?Validation?校驗(yàn)參數(shù),需要的朋友可以參考下
    2022-05-05

最新評(píng)論

东辽县| 邹城市| 安塞县| 久治县| 武山县| 沙坪坝区| 玉田县| 英德市| 广丰县| 平安县| 彭泽县| 绿春县| 葫芦岛市| 漠河县| 武安市| 蛟河市| 兴化市| 巢湖市| 宜昌市| 定边县| 屏南县| 民勤县| 龙江县| 东丽区| 定日县| 灵璧县| 长阳| 高清| 屏东县| 晋州市| 屏南县| 镇巴县| 遵义市| 十堰市| 兖州市| 浙江省| 驻马店市| 山西省| 天柱县| 普兰县| 正阳县|