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

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

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

一、概述
Java虛擬機(jī)在執(zhí)行Java程序的過程中會(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é)碼的行號指示器。在虛擬機(jī)的概念模型里,字節(jié)碼解釋器工作就是通過改變程序計(jì)數(shù)器的值來選擇下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都要依賴這個(gè)計(jì)數(shù)器來完成。

多線程中,為了讓線程切換后能恢復(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è)沒有規(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í)行完成的過程,就對應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中入棧到出棧的過程。

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

如果擴(kuò)展時(shí)無法申請到足夠的內(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ū)域的唯一目的就是存放對象實(shí)例 。

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

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

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

方法區(qū)

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

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

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

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

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

直接內(nèi)存

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

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

三、對象的創(chuàng)建、布局和訪問過程
對象的創(chuàng)建

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

類加載檢查通過后,虛擬機(jī)將為新生對象分配內(nèi)存。為對象分配空間的任務(wù)等同于把一塊確定大小的內(nèi)存從Java堆中劃分出來。分配的方式有兩種: 一種叫 指針碰撞 ,假設(shè)Java堆中內(nèi)存是絕對規(guī)整的,用過的和空閑的內(nèi)存各在一邊,中間放著一個(gè)指針作為分界點(diǎn)的指示器,分配內(nèi)存就是把那個(gè)指針向空閑空間的那邊挪動(dòng)一段與對象大小相等的距離。 另一種叫 空閑列表 :如果Java堆中的內(nèi)存不是規(guī)整的,虛擬機(jī)就需要維護(hù)一個(gè)列表,記錄哪個(gè)內(nèi)存塊是可用的,在分配的時(shí)候從列表中找到一塊足夠大的空間劃分給對象實(shí)例,并更新列表上的記錄。 采用哪種分配方式是由Java堆是否規(guī)整決定的,而Java堆是否規(guī)整是由所采用的垃圾收集器是否帶有壓縮整理功能決定的。 另 外一個(gè)需要考慮的問題就是對象創(chuàng)建時(shí)的線程安全問題,有兩種解決方案:一是對分配內(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)存空間初始化為零值。這一步操作保證了對象的實(shí)例字段在Java代碼中可以不賦初始值就可以直接使用。

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

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

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

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

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

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

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

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

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

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

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

相關(guān)文章

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

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

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

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

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

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

    Dubbo是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊和發(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)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • java實(shí)現(xiàn)簡單的客戶信息管理系統(tǒng)

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

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xià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生成測試報(bào)告過程圖解

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

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

    SpringBoot整合logback的示例代碼

    Logback是由log4j創(chuàng)始人設(shè)計(jì)的又一個(gè)開源日志組件,logback分為三個(gè)模塊,在文章開頭給大家介紹的很明確,接下來通過本文重點(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

最新評論

高邑县| 汤原县| 永宁县| 滨州市| 巫山县| 德兴市| 滨州市| 蓬莱市| 商城县| 襄垣县| 潜江市| 鄂温| 郁南县| 柘荣县| 龙里县| 莆田市| 且末县| 泸州市| 甘肃省| 罗源县| 乌兰察布市| 黎城县| 垦利县| 密云县| 新化县| 桑植县| 明溪县| 湾仔区| 盐亭县| 仙桃市| 武山县| 大埔区| 宁化县| 洮南市| 左云县| 伊春市| 镇宁| 色达县| 房山区| 西盟| 伊川县|