亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

下面就每一個區(qū)域進行闡述。

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

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

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

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

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

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

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

如果擴展時無法申請到足夠的內(nèi)存,就會拋出OutOfMemoryError異常。

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

會拋出stackOverflowError和OutOfMemoryError異常。

Java堆

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

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

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

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

方法區(qū)

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

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

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

運行時常量池:

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

直接內(nèi)存

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

相關(guān)文章

  • Spring?cloud如何實現(xiàn)FeignClient指定Zone調(diào)用

    Spring?cloud如何實現(xiàn)FeignClient指定Zone調(diào)用

    這篇文章主要介紹了Spring?cloud如何實現(xiàn)FeignClient指定Zone調(diào)用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 一文掌握J(rèn)ava開發(fā)工具Maven(簡單上手)

    一文掌握J(rèn)ava開發(fā)工具Maven(簡單上手)

    掌握maven的相關(guān)知識是Java開發(fā)必備的技能,今天通過本文從入門安裝開始,逐步深入講解maven的相關(guān)知識,包括maven的安裝到簡單上手maven項目開發(fā),感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • 關(guān)于java的包Package中同名類的沖突及其理解

    關(guān)于java的包Package中同名類的沖突及其理解

    這篇文章主要介紹了關(guān)于java的包Package中同名類的沖突及其理解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 基于springMvc+hibernate的web application的構(gòu)建

    基于springMvc+hibernate的web application的構(gòu)建

    下面小編就為大家?guī)硪黄趕pringMvc+hibernate的web application的構(gòu)建。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • SpringBoot框架RESTful接口設(shè)置跨域允許

    SpringBoot框架RESTful接口設(shè)置跨域允許

    這篇文章主要為大家詳細(xì)介紹了SpringBoot框架RESTful接口設(shè)置跨域允許,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Java實現(xiàn)電影院訂票系統(tǒng)代碼

    Java實現(xiàn)電影院訂票系統(tǒng)代碼

    這篇文章主要介紹了Java實現(xiàn)電影院訂票系統(tǒng)代碼,代碼實現(xiàn)了界面類登錄注冊類,用戶類等,具有一定參考價值,需要的朋友可以參考下。
    2017-11-11
  • java開發(fā)SpringBoot參數(shù)校驗過程示例教程

    java開發(fā)SpringBoot參數(shù)校驗過程示例教程

    這篇文章主要為大家介紹了SpringBoot如何進行參數(shù)校驗的過程示例詳解教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-10-10
  • SpringBoot構(gòu)建RESTful API的實現(xiàn)示例

    SpringBoot構(gòu)建RESTful API的實現(xiàn)示例

    本文主要介紹了SpringBoot構(gòu)建RESTful API的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Java中CyclicBarrier的理解與應(yīng)用詳解

    Java中CyclicBarrier的理解與應(yīng)用詳解

    這篇文章主要介紹了Java中CyclicBarrier的理解與應(yīng)用詳解,CyclicBarrier類是JUC框架中的工具類,也是一個同步輔助裝置:允許多個線程去等待直到全部線程抵達了公共的柵欄點,需要的朋友可以參考下
    2023-12-12
  • 新手初學(xué)Java繼承、封裝與多態(tài)

    新手初學(xué)Java繼承、封裝與多態(tài)

    封裝、繼承、多態(tài)三大特征是java中比較常用的,務(wù)必要掌握,下面給大家介紹Java封裝、繼承、多態(tài)三大特征的理解,有不清楚的朋友可以一起學(xué)習(xí)下
    2021-07-07

最新評論