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

JVM高階面試:Java8為什么使用元空間替換永久代?

開(kāi)發(fā) 前端
元空間(Metaspace)是 Java8 中引入的一個(gè)新概念,用來(lái)替代原來(lái)的永久代。與永久代不同,元空間并不在虛擬機(jī)中,而是存儲(chǔ)在本地內(nèi)存(Native Memory)。

1. 方法區(qū)簡(jiǎn)介

JVM 的內(nèi)存模型主要包括程序計(jì)數(shù)器(Program Counter Register)、虛擬機(jī)棧(VM Stack)、本地方法棧(Native Method Stack)、堆(Heap)和方法區(qū)(Method Area)。

方法區(qū)(Method Area)是所有線程共享的內(nèi)存區(qū)域,用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。

具體來(lái)說(shuō),方法區(qū)用來(lái)存儲(chǔ)以下數(shù)據(jù):

  1. 類的元數(shù)據(jù)信息:包括類的名稱、訪問(wèn)標(biāo)志、父類、接口、字段、方法等信息。
  2. 運(yùn)行時(shí)常量池:在Java代碼中,常量可以被直接定義在類或接口中,這些常量在編譯后被存儲(chǔ)在Class文件的常量池中,而運(yùn)行時(shí)常量池則是從Class文件中加載的。
  3. 靜態(tài)變量和常量:類的靜態(tài)變量和常量都存儲(chǔ)在方法區(qū)中,它們?cè)陬惣虞d的時(shí)候被初始化并分配內(nèi)存空間。
  4. 方法字節(jié)碼:在Java中,方法的字節(jié)碼被編譯成Class文件并存儲(chǔ)在方法區(qū)中。
  5. 即時(shí)編譯器(JIT)編譯后的代碼:為了提高程序的執(zhí)行效率,JIT會(huì)將熱點(diǎn)代碼編譯成本地機(jī)器碼并存儲(chǔ)在方法區(qū)中。

方法區(qū)只是 JVM 規(guī)范中定義的一個(gè)概念,針對(duì) Hotspot 虛擬機(jī),Java8 之前使用永久代(Permanent Generation,簡(jiǎn)稱 PermGen)實(shí)現(xiàn),而 Java8 之后使用元空間(Metaspace)實(shí)現(xiàn)。

JDK8 之前可以通過(guò) -XX:PermSize 和 -XX:MaxPermSize 來(lái)設(shè)置永久代大小,JDK8 之后,使用元空間替換了永久代,改為通過(guò) -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 來(lái)設(shè)置元空間大小。

圖片

2. 永久代問(wèn)題

2.1 內(nèi)存溢出

永久代的空間是有限制的,可以通過(guò) -XX:PermSize 設(shè)置永久代初始容量,通過(guò)-XX:MaxPermSize 設(shè)置永久代最大容量。

但是當(dāng)加載過(guò)多的類或者常量的時(shí)候,就可能導(dǎo)致永久代的空間不足,拋出 java.lang.OutOfMemoryError: PermGen space 異常。尤其是web應(yīng)用會(huì)使用很多框架,這些框架會(huì)動(dòng)態(tài)加載很多基礎(chǔ)類,更容易導(dǎo)致OOM。

2.2 垃圾回收效率低下

永久代中的類信息一般是在應(yīng)用程序運(yùn)行期間不會(huì)發(fā)生變化的,因此,如果開(kāi)啟了永久代的垃圾回收,就會(huì)造成大量的垃圾回收操作,導(dǎo)致垃圾回收效率低下,甚至?xí)饝?yīng)用程序的暫停。

此外,由于永久代主要存放 JVM 加載的類信息等永久存在的數(shù)據(jù),這使得它在垃圾回收過(guò)程中的回收效率相對(duì)較低。在某些情況下,頻繁觸發(fā)的 Full GC 不僅無(wú)法有效回收永久代空間,還會(huì)嚴(yán)重影響 JVM 的性能。

2.3 無(wú)法動(dòng)態(tài)調(diào)整大小

永久代的大小一旦被設(shè)置,就無(wú)法動(dòng)態(tài)調(diào)整,如果預(yù)估錯(cuò)誤,就可能導(dǎo)致浪費(fèi)內(nèi)存或內(nèi)存不足的問(wèn)題。

2.4 無(wú)法回收常量池中的內(nèi)存

在永久代中,常量池是一個(gè)非常重要的部分,但是其中的常量無(wú)法被回收,即使這些常量已經(jīng)不再被使用,也無(wú)法被垃圾回收器回收,這會(huì)浪費(fèi)內(nèi)存。

3. 元空間簡(jiǎn)介

元空間(Metaspace)是 Java8 中引入的一個(gè)新概念,用來(lái)替代原來(lái)的永久代。與永久代不同,元空間并不在虛擬機(jī)中,而是存儲(chǔ)在本地內(nèi)存(Native Memory)。

從 Java7 已經(jīng)開(kāi)始逐步移除永久代,在Java7中把 interned Strings 、 class statics 和 String Pool 從永久代移到堆中。在 Java8 中徹底移除了永久代,把將類的元數(shù)據(jù)信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼從永久代中移到了元空間中。

圖片

4. 元空間的優(yōu)點(diǎn)

與永久代相比,使用元空間使用方法區(qū)具有以下優(yōu)點(diǎn):

  • 突破內(nèi)存限制,減少OOM。 由于元空間使用的是本地內(nèi)存,而不是 JVM 內(nèi)存,因此理論上,其大小只受限于操作系統(tǒng)的實(shí)際可用內(nèi)存。這大大減少了內(nèi)存溢出的可能性。相較于永久代在 JVM 堆中預(yù)分配的有限空間,元空間的引入提供了更大的空間來(lái)存儲(chǔ)類元數(shù)據(jù)。
  • 提高 Full GC 的效率。 在永久代中,F(xiàn)ull GC 的觸發(fā)比較頻繁,而且效率較低。因?yàn)橛谰么写娣帕撕芏?JVM 需要的類信息,這些數(shù)據(jù)大多數(shù)是不會(huì)被清理的,所以 Full GC 往往無(wú)法回收多少空間。但在元空間模型中,由于字符串常量池已移至堆中,靜態(tài)變量也移至 Java 堆或者本地內(nèi)存,因此可以更有效地進(jìn)行垃圾回收,避免了因頻繁的 Full GC 導(dǎo)致的性能影響。
  • 滿足不同的類加載需求和動(dòng)態(tài)類加載的情況。 在一些大型的、模塊化的應(yīng)用中,可能需要加載大量的類,這就需要大量的元數(shù)據(jù)存儲(chǔ)空間。元空間可以動(dòng)態(tài)地調(diào)整大小,能更好地滿足這種需求。
  • 避免永久代調(diào)優(yōu)和大小設(shè)置的復(fù)雜性。 在 Java8 之前的版本中,通常需要手動(dòng)設(shè)置永久代的大小,以避免內(nèi)存溢出的錯(cuò)誤。這增加了應(yīng)用的配置和管理的復(fù)雜性。而元空間使用本地內(nèi)存,根據(jù)實(shí)際需求動(dòng)態(tài)調(diào)整,大大簡(jiǎn)化了內(nèi)存管理的復(fù)雜性。

5. 元空間問(wèn)題

盡管元空間解決了永久代的一些問(wèn)題,可能也同時(shí)引入了一些新問(wèn)題:

  • 可能導(dǎo)致本地內(nèi)存溢出:雖然元空間使用的是本地內(nèi)存,理論上其大小只受限于操作系統(tǒng)的實(shí)際可用內(nèi)存,但是如果元空間的使用不加以控制,可能會(huì)導(dǎo)致大量的本地內(nèi)存被占用,從而導(dǎo)致 OutOfMemoryError。
  • 內(nèi)存管理和調(diào)優(yōu)策略:永久代的內(nèi)存管理和調(diào)優(yōu)策略無(wú)法直接應(yīng)用到元空間,需要重新考慮和設(shè)計(jì)。例如,如何確定元空間的初始大小、最大大小,如何進(jìn)行垃圾回收,等等。

因此,雖然元空間為 JVM 的內(nèi)存管理帶來(lái)了新的可能,但也帶來(lái)了新的挑戰(zhàn)。為了充分利用元空間的優(yōu)勢(shì),開(kāi)發(fā)者需要理解其工作原理,掌握正確的使用和調(diào)優(yōu)方法。

6. 總結(jié)

Java8 選擇使用元空間(Metaspace)替代永久代(PermGen)是 JVM 內(nèi)存模型的一次重大改進(jìn)。解決了永久代面臨的空間限制、低效的垃圾回收、以及復(fù)雜的內(nèi)存管理等問(wèn)題。元空間利用本地內(nèi)存,能夠動(dòng)態(tài)調(diào)整大小,提供了更大的空間來(lái)存儲(chǔ)類元數(shù)據(jù),也更好地適應(yīng)了大型、模塊化應(yīng)用的需求。

但是元空間也引入了一些新問(wèn)題。如何避免本地內(nèi)存溢出,如何制定有效的內(nèi)存管理和調(diào)優(yōu)策略,都是開(kāi)發(fā)者需要重新考慮的問(wèn)題。

責(zé)任編輯:武曉燕 來(lái)源: 一燈架構(gòu)
相關(guān)推薦

2019-10-23 08:16:50

Java8JVM內(nèi)存

2023-02-13 15:03:33

JDKJavaHotSpot

2023-09-28 07:34:23

JDK廢棄永久代元空間

2022-01-17 22:09:50

JVM方法區(qū)數(shù)據(jù)

2024-12-16 08:30:00

JVMJava虛擬機(jī)Java

2023-05-12 07:40:01

Java8API工具

2021-03-16 08:35:14

Kubernetes Docker容器

2017-10-31 20:45:07

JavaJava8Optional

2022-06-01 16:13:51

元宇宙

2021-05-11 21:56:11

算法清除JVM

2020-12-01 07:18:35

Java8日期時(shí)間

2015-09-30 09:34:09

java8字母序列

2022-02-18 00:15:58

Linux指令CPU

2015-09-22 11:09:47

Java 8動(dòng)態(tài)代理

2019-09-17 15:30:13

Java編程語(yǔ)言

2023-07-26 07:13:55

函數(shù)接口Java 8

2021-01-29 07:37:07

內(nèi)存對(duì)象垃圾

2022-02-10 20:26:06

虛擬元宇宙網(wǎng)絡(luò)

2010-09-17 17:02:24

JVM參數(shù)

2022-07-19 07:02:47

JVMGC分代收集
點(diǎn)贊
收藏

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