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

Java基礎(chǔ)之創(chuàng)建虛擬機(jī)對象的過程詳細(xì)總結(jié)

 更新時(shí)間:2021年05月23日 09:44:04   作者:IT__learning  
本文基于虛擬機(jī)HotSpot和常用的內(nèi)存區(qū)域Java堆深入對象分配、布局和訪問的全過程,文中有非常詳細(xì)的圖文解說,對正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下

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

在這里插入圖片描述

1.1 new 類名

虛擬機(jī)遇到一條new指令時(shí),首先檢查這個(gè)指令的參數(shù)是否能在常量池中定位到一個(gè)類的符號引用,并檢查這個(gè)符號引用代表的類是否已經(jīng)被加載、解析和初始化過。如果沒有,先執(zhí)行相應(yīng)的類加載過程。

1.2 分配內(nèi)存

虛擬機(jī)為新生對象分配內(nèi)存。對象所需內(nèi)存大小在類加載完成后就可以確定,為對象分配內(nèi)存等同于把一塊確定大小的內(nèi)存從Java堆中劃分出來。

(1)內(nèi)存分配的方式有兩種:

指針碰撞: java堆如果規(guī)整,一邊是用過的內(nèi)存,一邊是空閑的內(nèi)存,中間一個(gè)指針作為邊界指示器; 分配內(nèi)存只需向空閑那邊移動(dòng)指針空出與對象大小相等的空間;

空閑列表: 如果不規(guī)整,即用過的和空閑的內(nèi)存相互交錯(cuò);則虛擬機(jī)需要維護(hù)一個(gè)列表,記錄哪些內(nèi)存可用;分配內(nèi)存時(shí)查表找到一個(gè)足夠大的內(nèi)存,并更新列表記錄。
選擇哪種分配方式是根據(jù)這個(gè)虛擬機(jī)所采用的垃圾收集器是否帶有壓縮整理功能決定的:如果虛擬機(jī)的虛擬器帶壓縮整理功能,則系統(tǒng)采用指針碰撞的內(nèi)存分配算法;否則采用空閑列表的算法。

(2)線程安全問題

并發(fā)時(shí),上面兩種方式分配內(nèi)存的操作都不是線程安全的,有兩種解決方案:
同步處理
JVM采用CAS(Compare and Swap)機(jī)制加上失敗重試的方式,保證更新操作的原子性;
CAS:有3個(gè)操作數(shù),內(nèi)存值V,舊的預(yù)期值A(chǔ),要修改的新值B。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí),將內(nèi)存值V修改為B,否則什么都不做;
本地線程分配緩沖區(qū)(TLAB)
把分配內(nèi)存的動(dòng)作按照線程劃分在不同的空間中進(jìn)行:每個(gè)線程在Java堆預(yù)先分配一小塊內(nèi)存,稱為本地線程分配緩沖區(qū)(Thread Local Allocation Buffer,TLAB);哪個(gè)線程需要分配內(nèi)存就從哪個(gè)線程的TLAB上分配;只有TLAB用完需要分配新的TLAB時(shí),才需要同步處理。
JVM通過"-XX:+/-UseTLAB"指定是否使用TLAB。

1.3 初始化零值

內(nèi)存分配完之后,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為零值。如果用TLAB,則在TLAB分配時(shí)進(jìn)行。這保證了程序中對象(及實(shí)例變量)不顯式初始賦零值,程序也能訪問到零值。

1.4 設(shè)置對象信息

虛擬機(jī)對對象進(jìn)行必要的設(shè)置,例如這個(gè)對象是哪個(gè)類的實(shí)例、 如何才能找到類的元數(shù)據(jù)信息、 對象的哈希碼、 對象的GC分代年齡等信息。這些信息存放在對象的對象頭(Object Header)之中。

1.5 構(gòu)造對象

執(zhí)行init方法,即按照程序員的意愿進(jìn)行初始化。至此真正可用的對象才算完全被構(gòu)造出來。

二、對象的內(nèi)存布局

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

2.1 對象頭

HotSpot虛擬機(jī)的對象頭包含兩部分:

(1)第一部分用于存儲對象自身運(yùn)行時(shí)數(shù)據(jù),這部分?jǐn)?shù)據(jù)的長度在32位和64位的虛擬機(jī)中分別為32bit和64bit,官方稱它為“Mark Word”。

在這里插入圖片描述

(2)另外一部分是類型指針,即對象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過這個(gè)指針來確定這個(gè)對象是那個(gè)類的實(shí)例。
并不是所有的虛擬機(jī)實(shí)現(xiàn)都必須在對象數(shù)據(jù)上保留類型指針,即查找對象的元數(shù)據(jù)信息并不一定要經(jīng)過對象本身。

另外,如果對象是一個(gè)Java數(shù)組,那在對象頭中還必須有一塊用于記錄數(shù)組長度的數(shù)據(jù),因?yàn)樘摂M機(jī)可以通過普通Java對象的元數(shù)據(jù)信息確定Java對象的大小,但是從數(shù)組的元數(shù)據(jù)中卻無法確定數(shù)組的大小。

2.2 實(shí)例數(shù)據(jù)

實(shí)例數(shù)據(jù)部分是對象真正存儲的有效信息,也是在程序代碼中所定義的各種類型的字段內(nèi)容。無論是從父類繼承下來的,還是在子類中定義的,都需要記錄起來。這部分的存儲順序會受到虛擬機(jī)分配策略參數(shù)(FiedsAllocationStyle)和字段在Java源碼中定義順序的影響。

HotSpot虛擬機(jī)默認(rèn)的分配策略為:longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers)。從分配策略中可以看出,相同寬度的字段總是被分配到一起。在滿足這個(gè)前提條件的情況下,在父類中定義的變量會出現(xiàn)在子類之前。如果CompactFieds參數(shù)值為true(默認(rèn)為true),那么子類中較窄的變量也可能會插入到父類變量的空隙之中。

2.3 對齊填充

對齊填充并不是必然存在的,也沒有特別的含義,他僅僅起占位符的作用。由于HotSpot VM的自動(dòng)內(nèi)存管理系統(tǒng)要求對象起始地址必須是8字節(jié)的整數(shù)倍,換句話說,就是對象的大小必須是8字節(jié)的整數(shù)倍,而對象頭部分正好是8字節(jié)的倍數(shù),因此,當(dāng)對象實(shí)例部分沒有對齊時(shí),就需要通過對齊填充來補(bǔ)全。

三、對象的訪問定位

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

3.1 使用句柄

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

在這里插入圖片描述

3.2 指針方式

如果以指針方式訪問,那么Java堆對象的布局中就必須考慮如何放置訪問類型數(shù)據(jù)的相關(guān)信息,而reference中存儲的直接就是對象地址,如果只是訪問對象本身,就會少一次間接訪問的開銷。

在這里插入圖片描述

四、兩種方式的比較

句柄訪問最大好處就是reference中存儲的是穩(wěn)定的句柄地址,在對象被移動(dòng)時(shí)只會改變句柄中的實(shí)例數(shù)據(jù)指針,而reference本身不需要修改。
指針訪問方式最大好處就是速度更快,節(jié)省了一次指針定位的時(shí)間開銷,由于對于下部分的訪問在Java中非常頻繁,因此此類開銷積少成多后也是一項(xiàng)非??捎^的執(zhí)行成本。

到此這篇關(guān)于Java基礎(chǔ)之創(chuàng)建虛擬機(jī)對象的過程詳細(xì)總結(jié)的文章就介紹到這了,更多相關(guān)虛擬機(jī)中對象的創(chuàng)建過程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java對象在JVM中的生命周期詳解

    Java對象在JVM中的生命周期詳解

    這篇文章主要介紹了Java對象在JVM中的生命周期詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-05-05
  • Java+Spring+MySql環(huán)境中安裝和配置MyBatis的教程

    Java+Spring+MySql環(huán)境中安裝和配置MyBatis的教程

    這篇文章主要介紹了Java+Spring+MySql環(huán)境中安裝和配置MyBatis的教程,MyBatis一般被用來增強(qiáng)數(shù)據(jù)庫操作,文中對MyBatis的主配置文件有較為詳細(xì)的講解,需要的朋友可以參考下
    2016-04-04
  • Java面向?qū)ο蠡A(chǔ)之多態(tài)性,抽象類和接口

    Java面向?qū)ο蠡A(chǔ)之多態(tài)性,抽象類和接口

    這篇文章主要介紹了Java面向?qū)ο蠡A(chǔ):多態(tài)性,抽象類和接口,文中代碼可以幫助各位更好的理解學(xué)習(xí),有需求的小伙伴可以參考下
    2020-05-05
  • Java實(shí)現(xiàn)的剪刀石頭布游戲示例

    Java實(shí)現(xiàn)的剪刀石頭布游戲示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的剪刀石頭布游戲,涉及java隨機(jī)數(shù)生成及邏輯判定等相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之棧

    Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之棧

    棧(stack)又名堆棧,它是一種運(yùn)算受限的線性表。限定僅在表尾進(jìn)行插入和刪除操作的線性表。這一端被稱為棧頂,相對地,把另一端稱為棧底,棧是基礎(chǔ)中的基礎(chǔ),如果你還沒掌握透徹就來接著往下看吧
    2022-02-02
  • JSON for java快速入門總結(jié)學(xué)習(xí)

    JSON for java快速入門總結(jié)學(xué)習(xí)

    這篇文章主要介紹了JSON for java入門總結(jié)學(xué)習(xí),有需要的可以了解一下。
    2016-11-11
  • Java中構(gòu)造、生成XML簡明教程

    Java中構(gòu)造、生成XML簡明教程

    這篇文章主要介紹了Java中構(gòu)造、生成XML簡明教程,本文通過dom4j包來完成,需要的朋友可以參考下
    2014-08-08
  • SpringBoot中引入MyBatisPlus的常規(guī)操作

    SpringBoot中引入MyBatisPlus的常規(guī)操作

    這篇文章主要介紹了SpringBoot中引入MyBatisPlus的常規(guī)操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 一文詳解Java中的監(jiān)聽器(Listener)

    一文詳解Java中的監(jiān)聽器(Listener)

    這篇文章主要介紹了Java中監(jiān)聽器(Listener)的相關(guān)資料,監(jiān)聽器模式是一種設(shè)計(jì)模式,用于處理異步事件和通知,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • Java軟件編程培訓(xùn)機(jī)構(gòu)靠譜嗎

    Java軟件編程培訓(xùn)機(jī)構(gòu)靠譜嗎

    隨著網(wǎng)絡(luò)信息化的快速發(fā)展,Java培訓(xùn)受到越來越多人的青睞,目前Java工程師的薪資水平在不斷攀升,但是有好多企業(yè)還是招不到合適的人才,為什么呢
    2017-04-04

最新評論

集贤县| 沈阳市| 江山市| 襄垣县| 四川省| 运城市| 武汉市| 伊吾县| 南阳市| 大方县| 娱乐| 虞城县| 二连浩特市| 融水| 永定县| 抚州市| 赣州市| 通化市| 兴宁市| 金堂县| 长泰县| 准格尔旗| 夹江县| 弥勒县| 武陟县| 井研县| 高邑县| 中方县| 石家庄市| 合阳县| 招远市| 乐安县| 吐鲁番市| 京山县| 合水县| 望都县| 泾源县| 大宁县| 永嘉县| 峨山| 平舆县|