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

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

這篇具有很好參考價值的文章主要介紹了【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

JVM系列整體欄目


內(nèi)容 鏈接地址
【一】初識虛擬機與java虛擬機 https://blog.csdn.net/zhenghuishengq/article/details/129544460
【二】jvm的類加載子系統(tǒng)以及jclasslib的基本使用 https://blog.csdn.net/zhenghuishengq/article/details/129610963
【三】運行時私有區(qū)域之虛擬機棧、程序計數(shù)器、本地方法棧 https://blog.csdn.net/zhenghuishengq/article/details/129684076
【四】運行時數(shù)據(jù)區(qū)共享區(qū)域之堆、逃逸分析 https://blog.csdn.net/zhenghuishengq/article/details/129796509
【五】運行時數(shù)據(jù)區(qū)共享區(qū)域之方法區(qū)、常量池 https://blog.csdn.net/zhenghuishengq/article/details/129958466

一,運行時數(shù)據(jù)區(qū)共享區(qū)域—方法區(qū)

1,方法區(qū)的基本概述

方法區(qū)和堆一樣,也是屬于運行時數(shù)據(jù)區(qū)中的共享區(qū)域,并且也屬于重要的一個內(nèi)存空間,該空間主要是配合堆棧一起工作。

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

如下面這行代碼,new User就是存在Java堆中,第一個User就是存在方法區(qū)中,第二個user就是作為局部變量表存儲在棧中。

User user = new User();
#方法區(qū):User
#棧:user
#堆:new User();

《Java虛擬機規(guī)范》中明確說明:“盡管所有的方法區(qū)在邏輯上是屬于堆的一部分,但一些簡單的實現(xiàn)可能不會選擇區(qū)進行垃圾回收或者進行壓縮”。但是對于HotSpot虛擬機而言,方法區(qū)還有一個別名就叫做Non-Heap(非堆),目的就是要和堆分開。因此,方法區(qū)可以看做是一塊獨立于Java堆的內(nèi)存空間

?? 方法區(qū)和java堆一樣,屬于是各個線程共享的區(qū)域

?? 方法區(qū)在Jvm啟動的時候被創(chuàng)建,他的物理內(nèi)存和堆一樣可以是不連續(xù)的

?? 方法區(qū)的大小和堆空間一樣,可以選擇固定大小或者可擴展

?? 方法區(qū)的大小決定了系統(tǒng)可以保存多少個類,如果系統(tǒng)定義了太多的類,導(dǎo)致方法區(qū)溢出,虛擬機同樣會拋出內(nèi)存溢出錯誤,如加載大量的第三方j(luò)ar包,Tomcat部署的工程過多,大量的動態(tài)反射類等

?? 關(guān)閉JVM之后,就會釋放這個區(qū)域的內(nèi)存

2,方法區(qū)的演進過程

這里主要是針對HotSpot虛擬機,在JDK8以前,習(xí)慣將方法區(qū)稱為永久代;從JDK8開始,使用了這個元空間取代了永久代。就相當于把這個方法區(qū)當成是一個接口,而永久代和元空間就是該接口的具體實現(xiàn)。

In JDK8,classes metadata is now stored in the navite heap and this space is called MetaSpace

方法區(qū)和這個永久代并不等價,《Java虛擬機規(guī)范》對如何實現(xiàn)方法區(qū),不做統(tǒng)一的要求。

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

到了這個 JDK8 之后,終于完全廢棄了永久代的概念,改用JRockit、J9一樣在本地內(nèi)存中實現(xiàn)的元空間來代替。

元空間的本質(zhì)和永久代類似,都是JVM規(guī)范中方法區(qū)實現(xiàn)的,不過元空間與永久代最大的區(qū)別在于:元空間不在虛擬機設(shè)置的內(nèi)存中,而是使用的是本地內(nèi)存。

永久代和元空間二者不只是名字變了,內(nèi)部結(jié)構(gòu)也調(diào)整了,根據(jù)《java虛擬機規(guī)范》的規(guī)定,如果方法區(qū)無法滿足新的內(nèi)存分配需求時,將拋出OOM異常。

3,方法區(qū)大小設(shè)置與OOM

方法區(qū)的大小不必是固定的,jvm可以根據(jù)應(yīng)用的需要動態(tài)調(diào)整。

3.1,方法區(qū)內(nèi)存大小的分配

在jdk1.8之前

?? 可以通過 -XX:PermSize 來設(shè)置永久代初始的分配空間,默認值為20.75M

?? 通過 -XX:MaxPermSize 來設(shè)置永久代最大的分配空間,32位機器默認是64M,64位機器為82M

?? 當JVM加載的類信息容量超過了這個值,會報異常OutOfMemoryError:PermGen

在jdk1.8及以后

?? 元數(shù)據(jù)區(qū)大小可以使用參數(shù) -XX:MetaspaceSize-XX:MaxMetaspaceSize 設(shè)置原始值和最大值

?? 默認值依賴平臺,windows下 -XX:MetaspaceSize 為21M,-XX:MaxMetaspaceSize 為-1,即沒有限制

?? 默認情況下,虛擬機會耗盡所有內(nèi)存,如果元數(shù)據(jù)區(qū)溢出,虛擬機會拋異常OutofMemoryError:Metaspace

?? 當內(nèi)存高于設(shè)置的21M時,就會觸發(fā)Full GC,F(xiàn)ull GC就會卸載掉沒用的類

?? 因此建議將這個初始內(nèi)存設(shè)置一個相對較高的值,以免頻繁觸發(fā)Full GC

3.2,OOM的解決方案

  • 要解決這些OOM異?;蛘遠eap space異常,一段手段是通過內(nèi)存印象分析工具堆dump出來的堆轉(zhuǎn)存儲快照進行分析,重點是確認內(nèi)存中的對象是否是必要的,也就是要分清楚是出現(xiàn)了內(nèi)存泄漏還是內(nèi)存溢出。
  • 如果是內(nèi)存泄漏,可進一步通過工具查看泄漏對象到GC Roots的引用鏈,于是就能找到泄漏對象是通過怎樣的路徑與GC Roots相關(guān)聯(lián)。在掌握了泄漏對象的信息,以及GC Roots引用鏈之后,就可以準確的定位到泄漏代碼的位置了。
  • 如果不存在內(nèi)存泄漏,換句話就是說內(nèi)存中的對象確實是還活著,那么就應(yīng)該檢查虛擬機的參數(shù),與機器內(nèi)存相比看是否還可以調(diào)大,從代碼上檢查是否存在某些對象的生命周期過長,持有時間過長等情況,從而減少運行期間的內(nèi)存消耗。

4,方法區(qū)的內(nèi)部結(jié)構(gòu)

4.1,方法區(qū)存儲數(shù)據(jù)概述

在將 .java 文件編譯成 .class字節(jié)碼文件之后,這個字節(jié)碼文件是需要存儲的,而類本身的一些信息,則需要存儲在這個方法區(qū)里面,除了類信息之外,這個運行時常量池也是存儲在這個方法區(qū)里面的。

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

在《深入理解Java虛擬機》這本書中,對方法區(qū)存儲內(nèi)容的概述如下:它用于存儲已被虛擬機加載的類型信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼緩存等。 但是隨著JDK的不斷迭代,其內(nèi)存存儲的東西也會有著稍小的變化。

類型信息:對加載的類型,包括類class、接口interface、枚舉enum、注解annotation等,JVM必須在方法區(qū)中存儲以下類型

? 這個類型的完整有效名稱,全名就是 包名.類名

? 直接父類的完整有效名,interface和Object都是沒有父類的

? 這個類型的修飾符,如public、static、final、abstract

? 直接接口的一個有序列表,如這個類可能實現(xiàn)多個接口

屬性信息:域的相關(guān)信息主要包括以下:域名稱、域類型、域修飾符等

方法信息:方法信息主要包括一些方法名稱、返回類型、參數(shù)的數(shù)量和類型、方法的修飾符、方法的字節(jié)碼、局部變量表以及其大小、異常表等

4.2,static final

在靜態(tài)變量中,一般是隨著累的加載而加載,他們成為類數(shù)據(jù)在邏輯上的一部分,并且類變量被類所有的實例共享,即使類實例不存在也可以進行訪問。

而被聲明的final的類變量的處理方法則不同,該變量在編譯階段就會被分配了;而沒有被聲明final的類變量,在準備階段進行初步的賦值,在初始化階段進行一個最終的賦值。

如寫一個Java測試類,定義一個被final修飾的類變量和不被final修飾的類變量,并且這個類型為基礎(chǔ)數(shù)據(jù)類型

public class Test {
    public static final int i = 10;
    public static  int k = 20;

    public static void main(String[] args) {
        System.out.println(i+k);
    }
}

然后在編譯好的文件中,輸入反編譯命令,并將最終輸出的文件加載到zhs.txt文件中

javap -v -p Test.class > zhs.txt

接下來重點分析這兩個變量,可以發(fā)現(xiàn)這個加了final修飾的i,在編譯階段就進行了分配,賦值為10;而沒有加final修飾的k,在編譯階段沒有賦予默認值,而是在準備階段賦值的默認值,在初始化階段賦予的最終值

public static final int i;
  descriptor: I
  flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
  ConstantValue: int 10

public static int k;
  descriptor: I
  flags: ACC_PUBLIC, ACC_STATIC

4.3,運行時常量池

4.3.1,什么是常量池

一個有效的字節(jié)碼文件除了包含類的版本信息、字段、方法以及接口等描述信息之外,還包含一項重要的信息,那就是常量池表(Constant Pool Table),其中包括各種字面量和對類型,字段和方法的符號引用,如下

Constant pool:
   #1 = Methodref          #6.#27         // java/lang/Object."<init>":()V
   #2 = Fieldref           #28.#29        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = Class              #30            // com/fc/v2/util/Test
   #4 = Fieldref           #3.#31         // com/fc/v2/util/Test.k:I

一個Java源文件在編譯之后會產(chǎn)生一個字節(jié)碼文件,而字節(jié)碼文件需要數(shù)據(jù)支持,通常這種數(shù)據(jù)量很大不能直接存儲到字節(jié)碼文件里面,因此就通過常量池的方式,提前將數(shù)據(jù)存儲在常量池中,然后根據(jù)引用去獲取對應(yīng)的數(shù)據(jù),如在棧幀的 動態(tài)鏈接 就是通過這種方式來獲取數(shù)據(jù)的。

在常量池中存儲的數(shù)據(jù)類型主要有:數(shù)量值,字符串值,類引用,字段引用,方法引用

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

4.3.2,什么是運行時常量池

上面提到了常量池,常量池是字節(jié)碼文件的一部分,用于存放編譯期生成的各個字面量和符號引用,這部分內(nèi)容在類加載之后存放到方法區(qū)的運行時常量池中;而運行時常量池是屬于方法區(qū)的一部分,接下來詳細的描述一下上面是運行時常量池

? 在將類和接口加載到虛擬機之后,就會創(chuàng)建對應(yīng)的運行時常量池

? JVM會為每個已加載的類型都維護一個常量池,池中的數(shù)據(jù)可以通過索引訪問

? 運行時常量池包含多種不同的常量,包括編譯期就已經(jīng)明確的數(shù)值,如棧幀的大小,以及運行期間才能獲取到的方法或者字段引用,此時不再是常量池中的符號地址#,而是具體的真實地址。

? 運行時常量池具備動態(tài)性,如實際大小可能比計算的大小大

? 當創(chuàng)建接口或者類的運行時常量池時,如果構(gòu)造的運行時常量池所需要的內(nèi)存空間超過了方法區(qū)所能提供的最大值,則JVM就會拋出OutOfMemoryError異常

5,方法區(qū)的使用

接下來查看一段簡單的代碼,如下

/**
 * @author zhenghuisheng
 * @date : 2023/4/4
 */
public class Test {
    public static void main(String[] args) {
        int x = 500;
        int y = 100;
        int a = x/y;
        int b = 50;
        System.out.println(a+b);
    }
}

然后編譯之后,通過jclasslib插件查看對應(yīng)的字節(jié)碼,在前面的章節(jié)又講如何安裝使用

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

其對應(yīng)的字節(jié)碼文件如下

 0 sipush 500
 3 istore_1
 4 bipush 100
 6 istore_2
 7 iload_1
 8 iload_2
 9 idiv
10 istore_3
11 bipush 50
13 istore 4
15 getstatic #2 <java/lang/System.out>
18 iload_3
19 iload 4
21 iadd
22 invokevirtual #3 <java/io/PrintStream.println>
25 return

這個具體的操作流程如下,由于沒有new對象,因此在下圖中暫時先不展示堆空間。

首先程序計數(shù)器的記錄的地址為0,并將這個500這個數(shù)值壓入到操作數(shù)棧中。

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

然后就是這個istore_1,將操作數(shù)棧中存儲的值存儲到本地變量表中。而這個本地變量表,如果是實例方法或者是構(gòu)造方法,第一個數(shù)據(jù)存儲的應(yīng)該是this,而這里的是static的靜態(tài)方法,因此第一個slot存儲的不是this。

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

后續(xù)的操作和上面的一樣,這個iload_1就是將數(shù)據(jù)從本地變量本中取出來放到操作數(shù)棧頂,iload_2原理一樣,然后結(jié)果這個idiv除法運算,將結(jié)果5存放在本地變量表3的位置

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

隨后就是將50入棧,也存儲到本地變量表中4的位置,然后通過這個getstatic #2,就是獲取常量池中的#2的位置,然后最終可以獲取到這個System類,out類和對應(yīng)的type屬性,然后加載到方法區(qū)中。如果這些類或者屬性在方法區(qū)中存在就不會進行加載,如果不存在就會將這些加載到方法區(qū)中,然后將這些#等符號的間接引用變成地址的直接引用。

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

然后通過這個iload3和iload4將本地變量表的數(shù)據(jù)加載到操作數(shù)棧中

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

然后再經(jīng)過iadd計算,再調(diào)用這個invokevirtual #3的符號引用,最終可以定位到一個打印操作,最終return結(jié)束

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

通過上圖可以發(fā)現(xiàn),無論是在哪一個操作,程序計數(shù)器都會指向?qū)?yīng)的執(zhí)行位置。

6,方法區(qū)的演進細節(jié)

在虛擬機中,只有HotSpot虛擬機才有永久代,JRockit和J9是不存在永久代的概念的。在HotSpot虛擬機的方法區(qū)變化如下(方法區(qū)是一種概念,永久代和元空間屬于具體實現(xiàn)):

  • 在jdk6及以前:有永久代,靜態(tài)變量存放在永久代上面
  • 在jdk7中:有永久代,但逐步去除,字符串常量池、靜態(tài)變量保存在堆中
  • 在jdk8及以后:無永久代,類型信息、字段、方法、常量保存在本地內(nèi)存的元空間中,字符串常量池和靜態(tài)變量在堆中

6.1,方法區(qū)的具體實現(xiàn)以及內(nèi)部組成的演進

jdk6的方法區(qū)的組成如下,也稱為永久代,其靜態(tài)變量,運行時常量池,字符串常量池等都是保存在這個永久代的里面,并且字符串常量池是屬于運行時常量池的一部分

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

而在jdk7開始,就將字符串常量池和靜態(tài)變量存放在堆里面

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

而從jdk8開始,永久代已經(jīng)不存在了,取而代之的是本地內(nèi)存的 元空間,會將運行時常量池,類信息等全部存儲在本地內(nèi)存中,并且靜態(tài)變量和字符串常量池都是存儲在堆中

【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)

在官方文檔中https://openjdk.org/jeps/122,也提到過這個刪除這個永久代的動機,如下,主要就是說參考了這個 JRockit 內(nèi)部的實現(xiàn),這樣用戶可以不必自己去配置這個永久代。這樣這塊空間可以不用jvm本身去管理,從而交給本地內(nèi)存區(qū)實現(xiàn)。

This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.

其實這項改動還是很有必要的,接下來從兩個方面來說明為啥要替換

  • 永久代的空間大小設(shè)置是很難確定的,在某些場景下,如果動態(tài)的加載類過多,就很容易出現(xiàn)OOM,比如一些Web項目。而元空間和永久代之間最大的區(qū)別在于:元空間不在虛擬機中,而是使用的是本地內(nèi)存,因此元空間的大小只受本地內(nèi)存限制
  • 永久代的調(diào)優(yōu)比較困難

6.2,字符串常量池為何要存儲到堆中

在jdk7的時候,將靜態(tài)變量和字符串常量池都存儲到了堆中,其主要原因是在永久代中,其觸發(fā)的回收效率很低,在full gc的時候才會觸發(fā)。而full gc的老年代空間不足,或者永久代空間不足時才會觸發(fā),因此這就導(dǎo)致了這個字符串常量池的回收率不高。

而在如今的開發(fā)中,可能會創(chuàng)建大量的字符串,如果還是存儲在方法區(qū)內(nèi)部,那么其回收率會比較低,很容易導(dǎo)致永久代的內(nèi)存不足,因此選擇將這個字符串常量池存放到堆中,這樣就可以快速的實現(xiàn)內(nèi)存回收。

7,方法區(qū)的垃圾回收機制

在運行時數(shù)據(jù)區(qū)中,方法區(qū)又被稱為non-heap,就是非堆的意思。并且在《java虛擬機規(guī)范》中描述,對方法區(qū)中的約束是非常寬松的,提到過不要求虛擬機在方法區(qū)中實現(xiàn)垃圾回收

一般來說這個區(qū)域的回收效果比較難令人滿意,但是有時又確實是有必要的,因此在HotSpot虛擬機中,方法區(qū)的垃圾回收主要是回收兩部分內(nèi)容:常量池中廢棄的常量和不再使用的類型

常量回收的策略就是只要該常量沒有被任何地方引用,就可以被回收,回收廢棄常量和回收Java堆的對象非常類似

類型回收的條件相對比較苛刻,需要同時的滿足以下三點條件:

  • 該類的實例被回收,該類以及對應(yīng)的子類在堆中不存在
  • 該類的類加載器已被回收
  • 該類的Class對象沒有任何地方被引用,無法在任何地方通過反射訪問到該類

滿足這三點條件也不是一定會進行回收,而是可能被允許回收。在大量的使用反射、動態(tài)代理、CGLib這些字節(jié)碼框架,動態(tài)生成Jsp等這些場景中,通常需要java虛擬機具備類型卸載的能力,以保證不會對方法區(qū)造成過大的壓力。文章來源地址http://www.zghlxwxcb.cn/news/detail-406782.html

到了這里,關(guān)于【jvm系列-05】精通運行時數(shù)據(jù)區(qū)共享區(qū)域---方法區(qū)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • JVM運行時數(shù)據(jù)區(qū)——堆內(nèi)的區(qū)域分布

    JVM運行時數(shù)據(jù)區(qū)——堆內(nèi)的區(qū)域分布

    1.堆內(nèi)的區(qū)域分布 堆是運行時數(shù)據(jù)區(qū) 最大 的一塊區(qū)域, 主要用來存放對象 ,堆是所有 線程公用 的,在JVM 啟動時就被創(chuàng)建 ,堆的 空間是可以調(diào)整 的,是GC(垃圾回收)的 重點區(qū)域 。 堆的內(nèi)存空間分區(qū):新生代+老年代 新生代又分為Eden(伊甸園)和Survivor(幸存者)區(qū)。 ?

    2024年02月16日
    瀏覽(16)
  • jvm復(fù)習(xí),深入理解java虛擬機一:運行時數(shù)據(jù)區(qū)域

    jvm復(fù)習(xí),深入理解java虛擬機一:運行時數(shù)據(jù)區(qū)域

    ? ? ? ? 程序計數(shù)器 (Program Counter Register) 它是程序控制流的指示器,簡單來說,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個獨立的程序計數(shù)器 ? ? ? ? ?Java虛擬機棧 (Java Virtual Machine Stack)也是線程私有的,它的生命周期 與線程相同。虛擬機棧描述

    2024年01月22日
    瀏覽(17)
  • 【Jvm】運行時數(shù)據(jù)區(qū)域(Runtime Data Area)原理及應(yīng)用場景

    【Jvm】運行時數(shù)據(jù)區(qū)域(Runtime Data Area)原理及應(yīng)用場景

    Jvm由 4個部分 組成,分為2個子系統(tǒng)和2個組件 ,2個子系統(tǒng)為 Class loader(類裝載)、Execution engine(執(zhí)行引擎) ;2個組件為 Runtime Data Area(運行時數(shù)據(jù)區(qū))、Native Interface(本地接口) 。 Class loader(類加載器) :根據(jù)給定的全限定名類名(如:Java.lang.Object)來裝載class文件到Runtime data area中的

    2024年02月20日
    瀏覽(20)
  • JVM系列 運行時數(shù)據(jù)區(qū)

    JVM系列 運行時數(shù)據(jù)區(qū)

    第一章 運行區(qū)實驗 JVM(Java虛擬機)運行區(qū)是Java程序在運行過程中被JVM所管理的內(nèi)存區(qū)域。它包括了Java程序運行時的堆(Heap)、棧(Stack)、方法區(qū)(Method Area)、本地方法棧(Native Method Stacks)、程序計數(shù)器和直接內(nèi)存(Direct Memory)等部分。 堆(Heap)是Java程序運行時用于

    2024年02月08日
    瀏覽(12)
  • java-JVM內(nèi)存區(qū)域&JVM運行時內(nèi)存

    java-JVM內(nèi)存區(qū)域&JVM運行時內(nèi)存

    JVM 內(nèi)存區(qū)域主要分為線程私有區(qū)域【程序計數(shù)器、虛擬機棧、本地方法區(qū)】、線程共享區(qū)域【JAVA 堆、方法區(qū)】、直接內(nèi)存。 線程私有數(shù)據(jù)區(qū)域生命周期與線程相同, 依賴用戶線程的啟動/結(jié)束 而 創(chuàng)建/銷毀(在 HotspotVM 內(nèi), 每個線程都與操作系統(tǒng)的本地線程直接映射, 因此這部

    2024年02月12日
    瀏覽(20)
  • JVM運行時區(qū)域——對象創(chuàng)建內(nèi)存分配過程

    JVM運行時區(qū)域——對象創(chuàng)建內(nèi)存分配過程

    ????????新創(chuàng)建的對象 , 都存放在伊甸園區(qū)域 ,當垃圾回收時,將伊甸園區(qū)域的垃圾數(shù)據(jù)銷毀,然后將存活的對象轉(zhuǎn)移到幸存者0區(qū)域,之后創(chuàng)建的新的對象還是存放在伊甸園區(qū)域,等到再次垃圾回收后,將伊甸園區(qū)域和幸存者0區(qū)域中存活的對象一起轉(zhuǎn)移到幸存者1區(qū)域中

    2024年02月15日
    瀏覽(22)
  • JVM運行時數(shù)據(jù)區(qū)——本地方法棧

    1.本地方法棧 本地方法棧里面存放的是 調(diào)用 的本地(Native)的方法,例如hashcode()。 本地方法棧也是線程 私有 的,本地方法是由 C 語言實現(xiàn)的。 如果 線程請求的棧容量 大于 本地方法棧允許的最大容量 則會出現(xiàn) 棧溢出 的問題。 其內(nèi)存空間可以調(diào)整。

    2024年02月16日
    瀏覽(16)
  • JVM理論(四)運行時數(shù)據(jù)區(qū)--堆/方法區(qū)

    JVM理論(四)運行時數(shù)據(jù)區(qū)--堆/方法區(qū)

    堆內(nèi)存邏輯上分為三部分 ?一個JVM實例只存在一個堆內(nèi)存,JVM啟動時創(chuàng)建堆區(qū),通常情況下也是最大的內(nèi)存空間,幾乎所有的對象實例都要在堆中分配內(nèi)存,所以堆也是垃圾回收的重點區(qū)域 堆是被所有線程共享的,在堆里面也可以劃分 線程私有的緩沖區(qū) ( TLAB -Thread Local Allocat

    2024年02月16日
    瀏覽(19)
  • JVM7:垃圾回收是什么?從運行時數(shù)據(jù)區(qū)看垃圾回收到底回收哪塊區(qū)域?垃圾回收如何去回收?垃圾回收策略,引用計數(shù)算法及循環(huán)引用問題,可達性分析算法

    JVM7:垃圾回收是什么?從運行時數(shù)據(jù)區(qū)看垃圾回收到底回收哪塊區(qū)域?垃圾回收如何去回收?垃圾回收策略,引用計數(shù)算法及循環(huán)引用問題,可達性分析算法

    在Java中,垃圾回收(Garbage Collection,簡稱GC),是自動管理內(nèi)存的機制。它負責檢測不再使用的對象,并釋放它們所占用的內(nèi)存,以供其他對象使用。 JVM內(nèi)存模型認識的差不多了,就應(yīng)該思考,什么樣的內(nèi)存模型適合什么樣的GC策略,包括垃圾回收為什么會出現(xiàn)。實際上,很多

    2024年02月11日
    瀏覽(20)
  • JVM零基礎(chǔ)到高級實戰(zhàn)之Java內(nèi)存區(qū)域本地方法棧

    JVM零基礎(chǔ)到高級實戰(zhàn)之Java內(nèi)存區(qū)域本地方法棧 JVM零基礎(chǔ)到高級實戰(zhàn)之Java內(nèi)存區(qū)域本地方法棧 本地方法棧是什么? 用于作用域本地方法執(zhí)行的一塊Java內(nèi)存區(qū)域 為什么要有本地方法棧? 與Java虛擬機棧相同,每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀(Stack Framel)用于存儲局部

    2024年02月09日
    瀏覽(13)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包