国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Java虛擬機(jī)學(xué)習(xí)2】HotSpot虛擬機(jī)下對象的創(chuàng)建及在Java堆中對象的內(nèi)存分配、布局和對象的訪問

這篇具有很好參考價值的文章主要介紹了【Java虛擬機(jī)學(xué)習(xí)2】HotSpot虛擬機(jī)下對象的創(chuàng)建及在Java堆中對象的內(nèi)存分配、布局和對象的訪問。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

HotSpot虛擬機(jī)下對象的生命周期、對象的創(chuàng)建及在Java堆中對象的內(nèi)存分配、布局和對象的訪問

一、對象的生命周期

對象的生命周期主要分為創(chuàng)建、使用、銷毀這三大階段。從它被創(chuàng)建的一刻開始,到它被垃圾收集器(Garbage Collector)回收的一刻結(jié)束

  • 對象的創(chuàng)建。包括:1、類的加載 2、內(nèi)存的分配 3、初始化零值 4、設(shè)置對象頭 5、執(zhí)行init方法(具體操作步驟請看上述內(nèi)容,其中步驟1的類加載還包括類的加載過程及類加載器及雙親委派型型)
  • 對象的使用。對象創(chuàng)建后就可以被使用,可以被其他的對象使用或是被直接使用,如果一個對象沒有被其他任何對象引用它,那么它就處于可回收狀態(tài)。
  • 對象的銷毀。當(dāng)對象不再被引用,或者程序結(jié)束時,垃圾收集器會將其標(biāo)記為可回收。具體的回收時間取決于垃圾收集器的運行策略。一旦對象被回收,它就不再存在

二、對象的創(chuàng)建

Step1:類加載檢查

虛擬機(jī)遇到一條new指令時,首先將檢查是否能在常量池中定位到這個類的符號引用,并且檢查這個符號引用代表的類是否已被加載過、驗證、準(zhǔn)備、解析過和初始化過。如果沒有,那必須先執(zhí)行相應(yīng)類加載過程。

(注意:
Java虛擬機(jī)中類的符號引用和方法的符號引用都存放在運行時常量池中,運行時常量池是方法區(qū)的一部分區(qū)域。運行時常量池是在類加載后在內(nèi)存中分配的一塊區(qū)域,用于存放編譯期生成的各種字面量和符號引用。在類裝載后,JVM會從class文件的常量池中把符號引用存放到運行時常量池中,并進(jìn)行解析,生成直接引用。)

Step2:分配內(nèi)存

類加載檢查通過后,接下來虛擬機(jī)將為新生對象分配內(nèi)存。對象所需的內(nèi)存大小在類加載完成后便可確定,為對象分配空間的任務(wù)等同于把一塊確定大小的內(nèi)存從 Java 堆中劃分出來。
分配方式有 “指針碰撞”“空閑列表” 兩種,選擇哪種分配方式由 Java 堆是否規(guī)整決定(即Java堆內(nèi)存是否連續(xù)),而 Java 堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。

問題一:內(nèi)存分配的兩種方式

指針碰撞:

  • 適用場合:堆內(nèi)存規(guī)整(即內(nèi)存連續(xù),沒有內(nèi)存碎片)的情況下。
  • 原理:用過的內(nèi)存全部整合到一邊,沒有用過的內(nèi)存放在另一邊,中間有一個分界指針,只需要向著沒用過的內(nèi)存方向?qū)⒃撝羔樢苿訉ο髢?nèi)存大小位置即可。
  • 使用該分配方式的 GC 收集器:Serial, ParNew

空閑列表

  • 適用場合:堆內(nèi)存不規(guī)整的情況下(內(nèi)存不連續(xù))。
  • 原理:虛擬機(jī)會維護(hù)一個列表,該列表中會記錄哪些內(nèi)存塊是可用的,在分配的時候,找一塊兒足夠大的內(nèi)存塊兒來劃分給對象實例,最后更新列表記錄。
  • 使用該分配方式的 GC 收集器:CMS

問題二:內(nèi)存分配并發(fā)問題

在創(chuàng)建對象的時候有一個很重要的問題,就是線程安全,因為在實際開發(fā)過程中,創(chuàng)建對象是很頻繁的事情,作為虛擬機(jī)來說,必須要保證線程是安全的,通常來講,虛擬機(jī)采用兩種方式來保證線程安全:

  • CAS+失敗重試: CAS是樂觀鎖的一種實現(xiàn)方式。所謂樂觀鎖就是,每次不加鎖而是假設(shè)沒有沖突而去完成某項操作,如果因為沖突失敗就重試,直到成功為止。虛擬機(jī)采用
    CAS 配上失敗重試的方式保證更新操作的原子性。
  • TLAB(Thread Local Allocation Buffer 線程本地緩沖區(qū)): 為每一個線程預(yù)先在 Eden 區(qū)(堆的一塊內(nèi)存區(qū)域)分配一塊兒內(nèi)存,JVM 在給線程中的對象分配內(nèi)存時,首先在 TLAB 分配,當(dāng)對象大于 TLAB 中的剩余內(nèi)存或 TLAB 的內(nèi)存已用盡時,再采用上述的 CAS 進(jìn)行內(nèi)存分配
    所以JVM虛擬機(jī)給對象分配內(nèi)存是通過TLAB(線程本地緩沖區(qū)技術(shù))和CAS原子操作來保證線程安全的。

Step3:初始化零值

內(nèi)存分配完成后,Java虛擬機(jī)會將分配到內(nèi)存空間的實例變量都初始化為零值或者空(不包括對象頭,即類對象下的屬性變量初始化為零或者空),這一步操作保證了對象實例字段在Java代碼中可以不賦初始值就直接使用

Step4:設(shè)置對象頭

初始化零值完成后,虛擬機(jī)要對對象進(jìn)行必要的設(shè)置,如:對象所屬的類的元數(shù)據(jù)信息、對象鎖的狀態(tài)、對象的哈希碼、對象的GC相關(guān)信息等,這些信息存放在對象頭中,即需要設(shè)置對象頭(對象頭會有不同的設(shè)置方式)。

問題:什么是對象頭,舉例說明一下呢?

對象頭(Object Header)是Java對象實例在內(nèi)存中的固定長度的數(shù)據(jù)結(jié)構(gòu),由Java虛擬機(jī)負(fù)責(zé)分配和管理。它包含了對象實例的運行時信息,如對象所屬的類的元數(shù)據(jù)信息對象的鎖狀態(tài)、GC相關(guān)信息等。通常情況下,對象頭的長度在32位和64位虛擬機(jī)中是不同的。在32位虛擬機(jī)中,對象頭占用8個字節(jié),在64位虛擬機(jī)中,對象頭占用12個或16個字節(jié)(具體長度取決于虛擬機(jī)實現(xiàn))。

舉個例子如下:
假設(shè)有一個名為Person的類,它的定義如下:

public class Person {
    private int id;
    private String name;
    private int age;
    
    // ...其它類成員省略...
}

當(dāng)我們創(chuàng)建一個Person對象時,Java虛擬機(jī)會為該對象分配一塊內(nèi)存空間,其中包括對象頭和實例變量。假設(shè)創(chuàng)建一個Person對象p1,它的內(nèi)存結(jié)構(gòu)大概如下(這里以32位虛擬機(jī)為例):

[對象頭 8B] [id變量 4B] [name變量 4B] [age變量 4B] [ padding 4B ]

其中,對象頭8個字節(jié)的內(nèi)容包含了Person類的元數(shù)據(jù)信息、對象的鎖狀態(tài)、GC相關(guān)信息等。實例變量包括了id、name和age三個變量,它們的值在初始化零值操作后會被賦為0或null,具體取決于變量的類型。

在后續(xù)的操作中,我們可以使用該對象的實例變量和方法,也可以使用Java虛擬機(jī)提供的API對對象頭進(jìn)行操作,以實現(xiàn)各種功能。例如,我們可以使用synchronized語句塊來實現(xiàn)多線程同步,這需要Java虛擬機(jī)在對象頭中記錄鎖狀態(tài),這樣就可以對對象進(jìn)行加鎖和解鎖。

Step5:執(zhí)行init方法

上面工作完成后,從虛擬機(jī)的角度來看,一個新的對象已經(jīng)產(chǎn)生了。
但是從java程序的角度出發(fā),對象的創(chuàng)建才開始,init 方法(構(gòu)造方法)還沒有執(zhí)行,所有字段都還為零或空。
所以一般來說,執(zhí)行new指令后會接著執(zhí)行init 方法,將對象按照程序員的意愿進(jìn)行初始化,這樣一個真正可用的對象才算完全產(chǎn)生出來。

三、對象的內(nèi)存分布

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

  • Hotspot 虛擬機(jī)的對象頭包括兩部分信息,第一部分用于存儲對象自身的運行時數(shù)據(jù)(哈希碼、GC 分代年齡、鎖狀態(tài)標(biāo)志等等),另一部分是類型指針,即對象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過這個指針來確定這個對象是哪個類的實例。
  • 實例數(shù)據(jù)部分:存儲的是對象真正的有效信息,即在程序中定義的各種類型的字段內(nèi)容。
  • 對齊填充部分對齊填充部分不是必然存在的,也沒有什么特殊的含義,僅僅起到占位作用。因為Hotspot虛擬機(jī)要求對象起始地址必須是8字節(jié)的整數(shù)倍,換句話說就是對象的大小必須是8字節(jié)的整數(shù)倍。而對象頭正好是8字節(jié)的倍數(shù)(1倍或2倍),因此當(dāng)對象的實例數(shù)據(jù)部分沒有對齊時就需要通過對齊填充來補全。

四、對象的訪問定位

對象的實例會存放在堆中,如何訪問到,那么如何訪問到對象呢?

java程序通過棧上的reference數(shù)據(jù)來操作堆上的具體對象。對象的訪問方式由虛擬機(jī)實現(xiàn)而定,目前主流的訪問方式:使用句柄、直接指針

  • (一)句柄
    如果使用句柄方式的話,那么java中將會劃分出一塊內(nèi)存來作為句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數(shù)據(jù)對象類型數(shù)據(jù)各自的具體地址信息。
    【Java虛擬機(jī)學(xué)習(xí)2】HotSpot虛擬機(jī)下對象的創(chuàng)建及在Java堆中對象的內(nèi)存分配、布局和對象的訪問,java,學(xué)習(xí),jvm
    優(yōu)點:
    使用句柄方式訪問對象最大的好處是reference中存儲的是穩(wěn)定的句柄地址,在對象被移動時(垃圾回收會造成堆中對象地址變動),只需要同步變動句柄池中對象實例數(shù)據(jù)指針即可。
    缺點
    訪問對象需要多訪問一次句柄池,多了一次指針定位的開銷。

  • (二)直接指針
    使用直接指針方式訪問,reference中存儲的就是堆中的對象地址,相比與使用句柄訪問節(jié)省了一次指針定位的時間開銷。而我們的Java應(yīng)用中,訪問對象是非常頻繁的,所以都使用直接指針的訪問方式一步到位。HotSpot虛擬機(jī)主要使用的就是這種方式來進(jìn)行對象訪問。
    【Java虛擬機(jī)學(xué)習(xí)2】HotSpot虛擬機(jī)下對象的創(chuàng)建及在Java堆中對象的內(nèi)存分配、布局和對象的訪問,java,學(xué)習(xí),jvm文章來源地址http://www.zghlxwxcb.cn/news/detail-599992.html

到了這里,關(guān)于【Java虛擬機(jī)學(xué)習(xí)2】HotSpot虛擬機(jī)下對象的創(chuàng)建及在Java堆中對象的內(nèi)存分配、布局和對象的訪問的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Java Platform, Standard Edition HotSpot 虛擬機(jī)垃圾收集調(diào)優(yōu)指南

    Java Platform, Standard Edition HotSpot 虛擬機(jī)垃圾收集調(diào)優(yōu)指南

    Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide (JDK8官方) 參考文檔 目錄 前言 觀眾 文檔輔助功能 相關(guān)文件 慣例 1 簡介 2 工效學(xué) 垃圾收集器、堆和運行時編譯器默認(rèn)選擇 基于行為的調(diào)優(yōu) 最長停頓時間目標(biāo) 吞吐量目標(biāo) Footprint占用空間目標(biāo) 調(diào)整策略 3 代

    2024年02月04日
    瀏覽(17)
  • 虛擬機(jī)下Linux系統(tǒng)磁盤擴(kuò)容

    虛擬機(jī)下Linux系統(tǒng)磁盤擴(kuò)容

    在VM虛擬機(jī)中,我們經(jīng)常會選擇默認(rèn)磁盤大小20G,用著用著才發(fā)現(xiàn)20G不夠用,服務(wù)啟動不了,就很尷尬,讓我們今天一起來學(xué)習(xí)下,如何在虛擬機(jī)給磁盤擴(kuò)容。 背景:我們使用 df -h 命令,發(fā)現(xiàn)磁盤使用率已經(jīng)37%,我們給此磁盤擴(kuò)容,簡單演示下擴(kuò)容的過程。 1:虛擬機(jī)關(guān)機(jī),

    2024年02月06日
    瀏覽(23)
  • 【雜】虛擬機(jī)下ubuntu無法訪問github

    【雜】虛擬機(jī)下ubuntu無法訪問github

    虛擬機(jī)下ubuntu訪問github有時無法訪問,本人嘗試多個解決方法,最終通過修改host解決。 解決方法一:修改host(見步驟1-4)。 其他可以嘗試的修改方法:關(guān)閉防火墻試試/切換節(jié)點 將github.com的ip地址添加到hosts文件末尾,如下圖所示。 將github.global.ssl.fastly.net的ip地址添加到

    2024年01月20日
    瀏覽(24)
  • CentOs虛擬機(jī)下openGauss的配置使用

    虛擬機(jī)平臺 VMware 服務(wù)器端 CentOS 7.9 本機(jī)系統(tǒng) Windows 10 部署版本 OpenGauss 1.1.0 虛擬機(jī) VMware 本機(jī)已配置,該部分省略 CentOS 7.9 安裝 下載鏡像源 CentOS-7-x86_64-DVD-2009.iso 虛擬機(jī)中選中鏡像進(jìn)行安裝 設(shè)置 內(nèi)存設(shè)置為 2GB 處理器設(shè)置為 2 網(wǎng)絡(luò)默認(rèn)即可 聲卡和打印機(jī)不使用直接進(jìn)行了移

    2024年03月10日
    瀏覽(22)
  • 9.Linux虛擬機(jī)下Hive的安裝配置

    9.Linux虛擬機(jī)下Hive的安裝配置

    Hadoop及相關(guān)組件搭建指導(dǎo)WeChat:h19396218469 hadoop-3.1.3 jdk-8u162-linux-x64 apache-hive-3.1.2-bin 本案例軟件包:鏈接:https://pan.baidu.com/s/1ighxbTNAWqobGpsX0qkD8w 提取碼:lkjh(若鏈接失效在下面評論,我會及時更新) 1.解壓Hive安裝包 先進(jìn)入文件存放目錄Downloads,再執(zhí)行如下命令。 上面的dblab

    2024年02月08日
    瀏覽(22)
  • [正式學(xué)習(xí)java①]——java項目結(jié)構(gòu),定義類和創(chuàng)建對象,一個標(biāo)準(zhǔn)javabean的書寫

    [正式學(xué)習(xí)java①]——java項目結(jié)構(gòu),定義類和創(chuàng)建對象,一個標(biāo)準(zhǔn)javabean的書寫

    目錄 一、創(chuàng)建第一個java文件 二、 初始類和對象 三、符合javabean規(guī)范的類 要想寫代碼,你得有文件啊 以前的創(chuàng)建方式: 右鍵新建文本文檔,開始寫代碼,寫完改后綴名,保存……這樣文件一旦多了很難管理 現(xiàn)在我們要規(guī)范項目結(jié)構(gòu) 每一個類就是一個java文件,每一個包存放

    2024年02月08日
    瀏覽(17)
  • 【在Linux虛擬機(jī)下如何添加磁盤并分區(qū)掛載】

    【在Linux虛擬機(jī)下如何添加磁盤并分區(qū)掛載】

    Linux文件系統(tǒng)是指Linux操作系統(tǒng)中用于組織、存儲和管理文件和目錄的一套機(jī)制。Linux文件系統(tǒng)采用樹形結(jié)構(gòu),以根目錄(/)作為根節(jié)點,所有文件和目錄都位于根目錄下或其子目錄中。類似樹結(jié)構(gòu)。 Linux支持多種不同類型的文件系統(tǒng),包括ext2、ext3、ext4、XFS、JFS、Btrfs等。其

    2024年02月06日
    瀏覽(25)
  • Ubuntu虛擬機(jī)下docker容器的自啟動設(shè)置

    一.背景 希望啟動虛擬機(jī)后,當(dāng)然docker自動啟動了的情況下,我們希望對應(yīng)的容器也自動啟動,比如tomcat或者redis。 二.設(shè)置過程 1.如果是已經(jīng)有容器實例了,修改吧 命令為:sudo docker update --restart=always? 容器id或者名稱 不知道名稱或者id,可以輸入命令查看:sudo docker ps -a 關(guān)

    2024年02月09日
    瀏覽(13)
  • VMware虛擬機(jī)下Ubuntu中g(shù)eth和truffle更換版本解決

    VMware虛擬機(jī)下Ubuntu中g(shù)eth和truffle更換版本解決

    虛擬機(jī):Vm16Pro 安裝系統(tǒng):Ubuntu20.04.6 Ubuntu官網(wǎng)地址:https://ubuntu.com/download/ 虛擬機(jī)Ubuntuan安裝教程??: VMware虛擬機(jī)安裝Ubuntu20.04詳細(xì)圖文教程_vmware ubuntu-CSDN博客? 1.在Ubuntu終端輸入一下命令: 2.查看geth版本 執(zhí)行上述命令后發(fā)現(xiàn)Geth的版本是1.13.5-stable,1.13.5-stable的版本在后續(xù)操

    2024年02月03日
    瀏覽(19)
  • 解決ubuntu新虛擬機(jī)下apt update報錯和git clone失敗的問題

    新的虛擬機(jī),安裝git發(fā)現(xiàn)apt不能正常使用,報錯如下 第一反應(yīng)是考慮到apt源配置可能有問題,用vi /etc/apt/source.list打開源發(fā)現(xiàn)沒有問題,用ping測試網(wǎng)絡(luò),ping百度報錯unkown host,ping 8.8.8.8可以通,應(yīng)該是域名解析錯誤,vi /etc/resolv.conf更改nameserver,輸入兩個8.8.8.8和8.8.4.4,然后

    2024年02月03日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包