自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JVM內(nèi)存區(qū)域劃分精講,你學(xué)會了嗎?

開發(fā) 前端
堆和方法區(qū)一樣也是各個(gè)線程共享的一塊內(nèi)存區(qū)域。堆也就是我們常說的 Java 堆,也是垃圾回收器主要管理的區(qū)域(方法區(qū)可以選擇不實(shí)現(xiàn)垃圾收集),“幾乎”所有的對象實(shí)例都在這里分配內(nèi)存。

引言

大家好,我們又見面了。有小伙伴說 JVM 內(nèi)存區(qū)域在學(xué)習(xí)與面試的時(shí)候常常理不清,為了解決這位小伙伴的困擾,我將通過兩篇文章為大家理清 JVM 內(nèi)存區(qū)域劃分,這篇是第一篇將為大家介紹 JVM 內(nèi)存區(qū)域的邏輯概念,下一篇將和大家嘮一嘮 HotSpot 虛擬機(jī)實(shí)現(xiàn)的一些小細(xì)節(jié)。安全帶系好,發(fā)車咯!

運(yùn)行時(shí)數(shù)據(jù)區(qū)

首先我們來明確一下運(yùn)行時(shí)數(shù)據(jù)區(qū)的概念,Java 虛擬機(jī)在執(zhí)行 Java 程序的過程中會將它所管理的內(nèi)存劃分為若干不同的數(shù)據(jù)區(qū),這些數(shù)據(jù)區(qū)就是運(yùn)行時(shí)數(shù)據(jù)區(qū),這些區(qū)域有各自的用途和生命周期。

根據(jù)《Java 虛擬機(jī)規(guī)范》的規(guī)定 JVM 所管理的內(nèi)存分為:虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器、方法區(qū)和堆這五種運(yùn)行時(shí)數(shù)據(jù)區(qū)。

圖片圖片

下面我們來分別介紹他們的邏輯概念。

需要注意,邏輯概念只是《Java虛擬機(jī)規(guī)范》中對運(yùn)行時(shí)數(shù)據(jù)區(qū)進(jìn)行的邏輯規(guī)范,不同的虛擬機(jī)的具體實(shí)現(xiàn)會略有差異。

虛擬機(jī)棧

虛擬機(jī)棧也是我們常說的 Java 棧,是線程私有的,在每一個(gè)線程啟動(dòng)的時(shí)候都會創(chuàng)建一個(gè)虛擬機(jī)棧。

虛擬機(jī)棧的生命周期和線程一致,虛擬機(jī)棧的內(nèi)部存儲著一個(gè)個(gè)棧幀,對應(yīng)著 Java 方法的一次次調(diào)用,方法被調(diào)用則壓棧,方法調(diào)用結(jié)束則出棧。

每一個(gè)棧幀內(nèi)部又存儲了局部變量表、方法返回地址、操作數(shù)棧、動(dòng)態(tài)鏈接等信息。

圖片圖片

在虛擬機(jī)棧規(guī)范了兩種異常情況。一是當(dāng)線程請求的棧深度大于虛擬機(jī)所允許的深度則會拋出 SOF(StackOverflowError)異常;二是當(dāng)虛擬機(jī)棧容量動(dòng)態(tài)擴(kuò)展時(shí)無法申請到足夠的內(nèi)存則會拋出 OOM(OutOfMemoryError)異常。

本地方法棧

本地方法棧的作用與虛擬機(jī)棧類似,只不過虛擬機(jī)棧服務(wù)于 Java 方法調(diào)用,本地方法棧服務(wù)于本地方法(native)調(diào)用。

本地方法棧也是線程私有的,且與虛擬機(jī)棧一致,在棧深度異常和擴(kuò)展失敗時(shí)分別會拋出 SOF 異常和 OOM 異常。

程序計(jì)數(shù)器

程序計(jì)數(shù)器用作當(dāng)前線程所執(zhí)行字節(jié)碼的行號指示器,同樣是線程私有的,它會存儲當(dāng)前正在執(zhí)行的字節(jié)碼指令地址,并在當(dāng)前字節(jié)碼指令執(zhí)行結(jié)束后切換為下一步需執(zhí)行的字節(jié)碼指令地址,線程就在程序計(jì)數(shù)器的推動(dòng)下一步步執(zhí)行。

如果當(dāng)前執(zhí)行的是本地方法,則程序計(jì)數(shù)器會存儲 Undefined。

方法區(qū)

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

圖片圖片

JVM 關(guān)閉后方法區(qū)將會被釋放。

方法區(qū)的常量主要被劃分為運(yùn)行時(shí)常量池和字符串常量池兩大區(qū)域。

字節(jié)碼文件中有一個(gè)區(qū)域叫做常量池表(Constant Pool Table),常量池表主要用于存儲編譯器生成的各種字面量與符號引用。

常量池表可以看作是一張表,虛擬機(jī)指令根據(jù)這張常量表找到要執(zhí)行的類名、方法名、參數(shù)類型、字面量等類型

而常量池表存儲的內(nèi)容將在類加載后存放到方法區(qū)的運(yùn)行時(shí)常量池中。

至于字符串常量池就是用于儲存字符串。

需要注意 Java 中的基本類型的包裝類的大部分都實(shí)現(xiàn)了常量池技術(shù),不過這里的常量池嚴(yán)格來說應(yīng)該叫做對象池,所以它們歸屬于堆,并不屬于方法區(qū)。

無論在不同版本的虛擬機(jī)實(shí)現(xiàn)中字符串常量池和靜態(tài)變量的存儲位置發(fā)生了怎樣的變化,在邏輯上這兩個(gè)區(qū)域是永遠(yuǎn)歸屬于方法區(qū)的。

方法區(qū)在內(nèi)存擴(kuò)展失敗的時(shí)候同樣會拋出 OOM 異常。

堆和方法區(qū)一樣也是各個(gè)線程共享的一塊內(nèi)存區(qū)域。堆也就是我們常說的 Java 堆,也是垃圾回收器主要管理的區(qū)域(方法區(qū)可以選擇不實(shí)現(xiàn)垃圾收集),“幾乎”所有的對象實(shí)例都在這里分配內(nèi)存。

在規(guī)范中,堆可以處于在物理上不連續(xù)的內(nèi)存空間,只要邏輯上連續(xù)即可,不過對于數(shù)組這種大對象,為了實(shí)現(xiàn)簡單和提高性能,大多數(shù)虛擬機(jī)實(shí)現(xiàn)都會考慮使用連續(xù)的內(nèi)存空間。

在當(dāng)前主流的虛擬機(jī)實(shí)現(xiàn)中,堆都可以通過-Xms 和-Xmx 設(shè)置容量,如果堆中的內(nèi)存不足以完成對象的實(shí)例分配,且堆無法再擴(kuò)展時(shí)就會拋出 OOM 異常,這也是 OOM 異常最頻發(fā)的一塊區(qū)域。

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2023-05-29 07:43:32

JVM內(nèi)存調(diào)優(yōu)

2023-01-31 08:02:18

2023-08-28 07:02:10

2023-07-31 07:33:05

JVM調(diào)優(yōu)Full GC

2024-02-02 09:00:14

內(nèi)存泄漏對象

2024-01-02 12:05:26

Java并發(fā)編程

2023-08-01 12:51:18

WebGPT機(jī)器學(xué)習(xí)模型

2023-01-10 08:43:15

定義DDD架構(gòu)

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-07-26 13:11:21

ChatGPT平臺工具

2024-01-19 08:25:38

死鎖Java通信

2022-06-04 07:46:41

HeapJVM

2022-06-16 07:50:35

數(shù)據(jù)結(jié)構(gòu)鏈表

2022-12-06 07:53:33

MySQL索引B+樹

2023-07-30 22:29:51

BDDMockitoAssert測試

2023-10-06 14:49:21

SentinelHystrixtimeout

2024-02-02 11:03:11

React數(shù)據(jù)Ref

2024-03-06 08:28:16

設(shè)計(jì)模式Java

2022-07-13 08:16:49

RocketMQRPC日志

2023-05-05 06:54:07

MySQL數(shù)據(jù)查詢
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號