91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM內存有哪些需要注意的

發布時間:2021-11-25 16:55:30 來源:億速云 閱讀:127 作者:柒染 欄目:編程語言

JVM內存有哪些需要注意的,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

前言

對于C語言開發的程序員來說,在內存管理方面,必須負責每一個對象的生命周期,從有到無。
對于Java程序員你來說,在虛擬機內存管理的幫助下,不需要為每個new對象都匹配free操作,內存泄露和內存溢出等問題也不太容易出現,不過也正是因為把內存管理交給了虛擬機,一旦運行中的程序出現了內存泄露問題,給排查過程造成很大困難。所以只有理解了Java虛擬機的運行機制,才能夠運籌帷幄于各種代碼。本文以HotSpot為例說說虛擬機的那些事。

JAVA虛擬機把管理的內存劃分為幾個不同的數據區。

JVM內存有哪些需要注意的

Java堆

Java堆是被所有線程共享的一塊內存區域,主要用于存放對象實例,Java虛擬機規范中有這樣一段描述:所有的對象實例和數據都要在堆上進行分配。為對象分配內存就是把一塊大小確定的內存從堆內存中劃分出來,通常有兩種方法實現:

1 、指針碰撞法
假設Java堆中內存時完整的,已分配的內存和空閑內存分別在不同的一側,通過一個指針作為分界點,需要分配內存時,僅僅需要把指針往空閑的一端移動與對象大小相等的距離。

2、空閑列表法
事實上,Java堆的內存并不是完整的,已分配的內存和空閑內存相互交錯,JVM通過維護一個列表,記錄可用的內存塊信息,當分配操作發生時,從列表中找到一個足夠大的內存塊分配給對象實例,并更新列表上的記錄。

對象創建是一個非常頻繁的行為,進行堆內存分配時還需要考慮多線程并發問題,可能出現正在給對象A分配內存,指針或記錄還未更新,對象B又同時分配到原來的內存,解決這個問題有兩種方案:
1、采用CAS保證數據更新操作的原子性;
2、把內存分配的行為按照線程進行劃分,在不同的空間中進行,每個線程在Java堆中預先分配一個內存塊,稱為本地線程分配緩沖(Thread Local Allocation Buffer, TLAB);

Java棧

Java棧是線程私有的,每個線程對應一個Java棧,每個線程在執行一個方法時會創建一個對應的棧幀(Stack Frame),棧幀負責存儲局部變量變量表、操作數棧、動態鏈接和方法返回地址等信息。每個方法的調用過程,相當于棧幀在Java棧的入棧和出棧過程。

JVM內存有哪些需要注意的

局部變量表 用于存放方法參數和方法內部定義的局部變量,其大小在代碼編譯期間已經確定,在方法運行期間不會改變。局部變量表以變量槽(Slot)為最小存儲單位,每個Slot能夠存放一個boolean、byte、char、shot、int、float、reference和returnAddress類型的32位數據,對于64位的數據類型long和double,虛擬機會以高位對齊的方式為其分配兩個連續的Slot空間。

在方法執行時,如果是實例方法,即非static方法,局部變量表中第0位Slot默認存放對象實例的引用,在方法中可以通過關鍵字 this 進行訪問,方法參數按照參數列表順序,從第1位Slot開始分配,方法內部變量則按照定義順序進行分配其余的Slot。

class test {
    public int calc(int a, int b, String operation) {
        operation = "+";        return  a + b;
    }    public void main(String args[]) {
        calc(100, 200, "+");
    }
}

對應的局部變量表如下:

JVM內存有哪些需要注意的

使用 javap -c 命令查看方法calc的字節碼

JVM內存有哪些需要注意的

其中iload_1和iload_2分別從局部變量表中的第1位和第2位中加載數據。

方法區

方法區和Java堆一樣,是所有線程共享的內存區域,用于存放已被虛擬機加載的類信息、常量、靜態變量和即時編譯器編譯后的代碼等數據。
運行時常量池是方法區的一部分,用于存放編譯期間生成的各種字面常量和符號引用。

指令計數器

指令計數器是線程私有的,每個線程都有獨立的指令計數器,計數器記錄著虛擬機正在執行的字節碼指令的地址,分支、循環、跳轉、異常處理和線程恢復等操作都依賴這個計數器完成。如果線程執行的是native方法,這個計數器則為空。

對象的內存布局

對象在內存中布局可以分成三塊區域:對象頭、實例數據和對齊填充。
1、對象頭
對象頭包括兩部分信息:運行時數據和類型指針,如果對象是一個數組,還需要一塊用于記錄數組長度的數據。

1.1、運行時數據包括哈希碼(HashCode)、GC分代年齡、鎖狀態標志、線程持有的鎖、偏向鎖ID和偏向時間戳等,這部分數據在32位和64位虛擬機中的長度分別為32bit和64bit,官方稱為"Mark Word"。Mark Word被設計成非固定的數據結構,以實現在有限空間內保存盡可能多的數據。
32位的虛擬機中,對象未被鎖定的狀態下,Mark Word的32bit中25bit存儲對象的HashCode、4bit存儲對象分代年齡、2bit存儲鎖標志位、1bit固定為0,具體如下:

JVM內存有哪些需要注意的

其它狀態(輕量級鎖定、重量級鎖定、GC鎖定、可偏向鎖)下Mark Word的存儲內容如下:

JVM內存有哪些需要注意的


1.2、對象頭的類型指針指向該對象的類元數據,虛擬機通過這個指針可以確定該對象是哪個類的實例。

2、實例數據
實例數據就是在程序代碼中所定義的各種類型的字段,包括從父類繼承的,這部分的存儲順序會受到虛擬機分配策略和字段在源碼中定義順序的影響。
3、對齊填充
由于HotSpot的自動內存管理要求對象的起始地址必須是8字節的整數倍,即對象的大小必須是8字節的整數倍,對象頭的數據正好是8的整數倍,所以當實例數據不夠8字節整數倍時,需要通過對齊填充進行補全。

關于JVM內存有哪些需要注意的問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jvm
AI

荥阳市| 伊川县| 苏州市| 许昌市| 黄平县| 丹巴县| 罗甸县| 武胜县| 呈贡县| 高台县| 麦盖提县| 泌阳县| 东明县| 晋宁县| 奉化市| 永清县| 厦门市| 南通市| 麻栗坡县| 襄樊市| 连山| 普陀区| 尼木县| 惠安县| 仪陇县| 晋城| 积石山| 临高县| 开鲁县| 儋州市| 福泉市| 西乌珠穆沁旗| 中江县| 兴业县| 文成县| 婺源县| 榆社县| 吉林市| 弥勒县| 托克托县| 眉山市|