java面試彙總:JVM篇!

Java_Yhua發表於2020-12-04

1、知識點彙總

JVM是Java執行基礎,面試時一定會遇到JVM的有關問題,內容相對集中,但對只是深度要求較高.
其中記憶體模型,類載入機制,GC是重點方面.效能調優部分更偏向應用,重點突出實踐能力.編譯器優化和執
行模式部分偏向於理論基礎,重點掌握知識點.
需瞭解
記憶體模型各部分作用,儲存哪些資料.
類載入雙親委派載入機制,常用載入器分別載入哪種型別的類.
GC分代回收的思想和依據以及不同垃圾回收演算法的回收思路和適合場景.
效能調優常有JVM優化引數作用,引數調優的依據,常用的JVM分析工具能分析哪些問題以及使用方法.
執行模式解釋/編譯/混合模式的優缺點,Java7提供的分層編譯技術,JIT即時編譯技術,OSR棧上替換,C1/C2
編譯器針對的場景,C2針對的是server模式,優化更激進.新技術方面Java10的graal編譯器
編譯器優化javac的編譯過程,ast抽象語法樹,編譯器優化和執行器優化.

2、知識點詳解:

1、JVM記憶體模型:
執行緒獨佔:棧,本地方法棧,程式計數器
執行緒共享:堆,方法區
2、棧:
又稱方法棧,執行緒私有的,執行緒執行方法是都會建立一個棧陣,用來儲存區域性變數表,操作棧,動態連結,方法
出口等資訊.呼叫方法時執行入棧,方法返回式執行出棧.
3、本地方法棧
與棧類似,也是用來儲存執行方法的資訊.執行Java方法是使用棧,執行Native方法時使用本地方法棧.
4、程式計數器
儲存著當前執行緒執行的位元組碼位置,每個執行緒工作時都有獨立的計數器,只為執行Java方法服務,執行
Native方法時,程式計數器為空.
5、堆
JVM記憶體管理最大的一塊,對被執行緒共享,目的是存放物件的例項,幾乎所欲的物件例項都會放在這裡,當堆
沒有可用空間時,會丟擲OOM異常.根據物件的存活週期不同,JVM把物件進行分代管理,由垃圾回收器進行
垃圾的回收管理
6、方法區:
又稱非堆區,用於儲存已被虛擬機器載入的類資訊,常量,靜態變數,即時編譯器優化後的程式碼等資料.1.7的永
久代和1.8的元空間都是方法區的一種實現
7、JVM 記憶體可見性
image.png

JMM是定義程式中變數的訪問規則,執行緒對於變數的操作只能在自己的工作記憶體中進行,而不能直接對主
記憶體操作.由於指令重排序,讀寫的順序會被打亂,因此JMM需要提供原子性,可見性,有序性保證.
image.png

3、類載入與解除安裝

載入過程
image.png

其中驗證,準備,解析合稱連結
載入通過類的完全限定名,查詢此類位元組碼檔案,利用位元組碼檔案建立Class物件.
驗證確保Class檔案符合當前虛擬機器的要求,不會危害到虛擬機器自身安全.
準備進行記憶體分配,為static修飾的類變數分配記憶體,並設定初始值(0或null).不包含final修飾的靜態變數,
因為final變數在編譯時分配.
解析將常量池中的符號引用替換為直接引用的過程.直接引用為直接指向目標的指標或者相對偏移量等.
初始化主要完成靜態塊執行以及靜態變數的賦值.先初始化父類,再初始化當前類.只有對類主動使用時才
會初始化.
觸發條件包括,建立類的例項時,訪問類的靜態方法或靜態變數的時候,使用Class.forName反射類的時候,
或者某個子類初始化的時候.
Java自帶的載入器載入的類,在虛擬機器的生命週期中是不會被解除安裝的,只有使用者自定義的載入器載入的類
才可以被卸.
1、載入機制-雙親委派模式
image.png

雙親委派模式,即載入器載入類時先把請求委託給自己的父類載入器執行,直到頂層的啟動類載入器.父類
載入器能夠完成載入則成功返回,不能則子類載入器才自己嘗試載入.*
優點:

  1. 避免類的重複載入
  2. 避免Java的核心API被篡改
    2、分代回收
    分代回收基於兩個事實:大部分物件很快就不使用了,還有一部分不會立即無用,但也不會持續很長時間.
    image.png

年輕代->標記-複製
老年代->標記-清除
3、回收演算法
a、G1演算法
1.9後預設的垃圾回收演算法,特點保持高回收率的同時減少停頓.採用每次只清理一部分,而不是清理全部的
增量式清理,以保證停頓時間不會過長
其取消了年輕代與老年代的物理劃分,但仍屬於分代收集器,演算法將堆分為若干個邏輯區域(region),一部分
用作年輕代,一部分用作老年代,還有用來儲存巨型物件的分割槽. 同CMS相同,會遍歷所有物件,標記引用情況,清除物件後會對區域進行復制移動,以整合碎片空間.
年輕代回收:
並行複製採用複製演算法,並行收集,會StopTheWorld.
老年代回收:
會對年輕代一併回收
初始標記完成堆root物件的標記,會StopTheWorld.
併發標記 GC執行緒和應用執行緒併發執行.
最終標記完成三色標記週期,會StopTheWorld.
複製/清楚會優先對可回收空間加大的區域進行回收
b、ZGC演算法
前面提供的高效垃圾回收演算法,針對大堆記憶體設計,可以處理TB級別的堆,可以做到10ms以下的回收停頓
時間.
image.png

點這裡-》》》》》》

  • 著色指標
  • 讀屏障
  • 併發處理
  • 基於region
  • 記憶體壓縮(整理)
    roots標記:標記root物件,會StopTheWorld.
    併發標記:利用讀屏障與應用執行緒一起執行標記,可能會發生StopTheWorld.
    清除會清理標記為不可用的物件. roots重定位:是對存活的物件進行移動,以騰出大塊記憶體空間,減少碎片產生.重定位最開始會
    StopTheWorld,卻決於重定位集與物件總活動集的比例.
    併發重定位與併發標記類似.

4、簡述一下JVM的記憶體模型

1.JVM記憶體模型簡介
JVM定義了不同執行時資料區,他們是用來執行應用程式的。某些區域隨著JVM啟動及銷燬,另外一些
區域的資料是執行緒性獨立的,隨著執行緒建立和銷燬。jvm記憶體模型總體架構圖如下:(摘自oracle官方
網站)
image.png

JVM在執行Java程式時,會把它管理的記憶體劃分為若干個的區域,每個區域都有自己的用途和建立銷燬
時間。如下圖所示,可以分為兩大部分,執行緒私有區和共享區。下圖是根據自己理解畫的一個JVM記憶體
模型架構圖:
image.png
JVM記憶體分為執行緒私有區和執行緒共享區

執行緒私有區
1、程式計數器
當同時進行的執行緒數超過CPU數或其核心數時,就要通過時間片輪詢分派CPU的時間資源,不免發生線
程切換。這時,每個執行緒就需要一個屬於自己的計數器來記錄下一條要執行的指令。如果執行的是JAVA
方法,計數器記錄正在執行的java位元組碼地址,如果執行的是native方法,則計數器為空。
2、虛擬機器棧
執行緒私有的,與執行緒在同一時間建立。管理JAVA方法執行的記憶體模型。每個方法執行時都會建立一個楨
棧來儲存方法的的變數表、運算元棧、動態連結方法、返回值、返回地址等資訊。棧的大小決定了方法
呼叫的可達深度(遞迴多少層次,或巢狀呼叫多少層其他方法,-Xss引數可以設定虛擬機器棧大小)。棧
的大小可以是固定的,或者是動態擴充套件的。如果請求的棧深度大於最大可用深度,則丟擲
stackOverflowError;如果棧是可動態擴充套件的,但沒有記憶體空間支援擴充套件,則丟擲
OutofMemoryError。
使用jclasslib工具可以檢視class類檔案的結構。下圖為棧幀結構圖:
image.png

3、本地方法棧
與虛擬機器棧作用相似。但它不是為Java方法服務的,而是本地方法(C語言)。由於規範對這塊沒有強
制要求,不同虛擬機器實現方法不同。

執行緒共享區
1、方法區
執行緒共享的,用於存放被虛擬機器載入的類的後設資料資訊,如常量、靜態變數和即時編譯器編譯後的代
碼。若要分代,算是永久代(老年代),以前類大多“static”的,很少被解除安裝或收集,現回收廢棄常量和
無用的類。其中執行時常量池存放編譯生成的各種常量。(如果hotspot虛擬機器確定一個類的定義資訊
不會被使用,也會將其回收。回收的基本條件至少有:所有該類的例項被回收,而且裝載該類的
ClassLoader被回收)
2、堆
存放物件例項和陣列,是垃圾回收的主要區域,分為新生代和老年代。剛建立的物件在新生代的Eden
區中,經過GC後進入新生代的S0區中,再經過GC進入新生代的S1區中,15次GC後仍存在就進入老年
代。這是按照一種回收機制進行劃分的,不是固定的。若堆的空間不夠例項分配,則
OutOfMemoryError。
image.png

5、堆和棧的區別

棧是執行時單位,代表著邏輯,內含基本資料型別和堆中物件引用,所在區域連續,沒有碎片;堆是存
儲單位,代表著資料,可被多個棧共享(包括成員中基本資料型別、引用和引用物件),所在區域不連
續,會有碎片。
1、功能不同
棧記憶體用來儲存區域性變數和方法呼叫,而堆記憶體用來儲存Java中的物件。無論是成員變數,區域性變數,
還是類變數,它們指向的物件都儲存在堆記憶體中。
2、共享性不同
棧記憶體是執行緒私有的。
堆記憶體是所有執行緒共有的。
3、異常錯誤不同
如果棧記憶體或者堆記憶體不足都會丟擲異常。
棧空間不足:java.lang.StackOverFlowError。
堆空間不足:java.lang.OutOfMemoryError。
4、空間大小
棧的空間大小遠遠小於堆的。
###6、 什麼時候會觸發FullGC
除直接呼叫System.gc外,觸發Full GC執行的情況有如下四種。
1. 舊生代空間不足
舊生代空間只有在新生代物件轉入及建立為大物件、大陣列時才會出現不足的現象,當執行Full GC後空
間仍然不足,則丟擲如下錯誤:
java.lang.OutOfMemoryError: Java heap space
為避免以上兩種狀況引起的FullGC,調優時應儘量做到讓物件在Minor GC階段被回收、讓物件在新生
代多存活一段時間及不要建立過大的物件及陣列。
Young Generation 即圖中的Eden + From Space(s0) + To Space(s1) Eden 存放新生的物件 Survivor Space 有兩個,存放每次垃圾回收後存活的物件(s0+s1) Old Generation Tenured Generation 即圖中的Old Space 主要存放應用程式中生命週期長的存活物件
2. Permanet Generation空間滿
PermanetGeneration中存放的為一些class的資訊等,當系統中要載入的類、反射的類和呼叫的方法較
多時,Permanet Generation可能會被佔滿,在未配置為採用CMS GC的情況下會執行Full GC。如果經
過Full GC仍然回收不了,那麼JVM會丟擲如下錯誤資訊:
java.lang.OutOfMemoryError: PermGen space
為避免Perm Gen佔滿造成Full GC現象,可採用的方法為增大Perm Gen空間或轉為使用CMS GC。
3. CMS GC時出現promotion failed和concurrent mode failure
對於採用CMS進行舊生代GC的程式而言,尤其要注意GC日誌中是否有promotion failed和concurrent
mode failure兩種狀況,當這兩種狀況出現時可能會觸發Full GC。
promotionfailed是在進行Minor GC時,survivor space放不下、物件只能放入舊生代,而此時舊生代
也放不下造成的;concurrent mode failure是在執行CMS GC的過程中同時有物件要放入舊生代,而此
時舊生代空間不足造成的。
應對措施為:增大survivorspace、舊生代空間或調低觸發併發GC的比率,但在JDK 5.0+、6.0+的版本
中有可能會由於JDK的bug29導致CMS在remark完畢後很久才觸發sweeping動作。對於這種狀況,可
通過設定-XX:CMSMaxAbortablePrecleanTime=5(單位為ms)來避免。
4. 統計得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間
這是一個較為複雜的觸發情況,Hotspot為了避免由於新生代物件晉升到舊生代導致舊生代空間不足的
現象,在進行Minor GC時,做了一個判斷,如果之前統計所得到的Minor GC晉升到舊生代的平均大小
大於舊生代的剩餘空間,那麼就直接觸發Full GC。
例如程式第一次觸發MinorGC後,有6MB的物件晉升到舊生代,那麼當下一次Minor GC發生時,首先
檢查舊生代的剩餘空間是否大於6MB,如果小於6MB,則執行Full GC。
當新生代採用PSGC時,方式稍有不同,PS GC是在Minor GC後也會檢查,例如上面的例子中第一次
Minor GC後,PS GC會檢查此時舊生代的剩餘空間是否大於6MB,如小於,則觸發對舊生代的回收。
除了以上4種狀況外,對於使用RMI來進行RPC或管理的Sun JDK應用而言,預設情況下會一小時執行一
次Full GC。可通過在啟動時通過- java-Dsun.rmi.dgc.client.gcInterval=3600000來設定Full GC執行的
間隔時間或通過-XX:+ DisableExplicitGC來禁止RMI呼叫System.gc。

7、什麼是Java虛擬機器?為什麼Java被稱作是“平臺無關的程式語言”?

Java虛擬機器是一個可以執行Java位元組碼的虛擬機器程式。Java原始檔被編譯成能被Java虛擬機器執行的位元組
碼檔案。 Java被設計成允許應用程式可以執行在任意的平臺,而不需要程式設計師為每一個平臺單獨重寫或
者是重新編譯。Java虛擬機器讓這個變為可能,因為它知道底層硬體平臺的指令長度和其他特性。

8、Java記憶體結構

image.png

點這裡-》》》》》》》

方法區和對是所有執行緒共享的記憶體區域;而java棧、本地方法棧和程式設計師計數器是執行是執行緒私有的內
存區域。

  • Java堆(Heap),是Java虛擬機器所管理的記憶體中最大的一塊。Java堆是被所有執行緒共享的一塊記憶體
    區域,在虛擬機器啟動時建立。此記憶體區域的唯一目的就是存放物件例項,幾乎所有的物件例項都在
    這裡分配記憶體。

  • 方法區(Method Area),方法區(Method Area)與Java堆一樣,是各個執行緒共享的記憶體區域,
    它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。

  • 程式計數器(Program Counter Register),程式計數器(Program Counter Register)是一塊較
    小的記憶體空間,它的作用可以看做是當前執行緒所執行的位元組碼的行號指示器。

  • JVM棧(JVM Stacks),與程式計數器一樣,Java虛擬機器棧(Java Virtual Machine Stacks)也是線
    程私有的,它的生命週期與執行緒相同。虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法被執
    行的時候都會同時建立一個棧幀(Stack Frame)用於儲存區域性變數表、操作棧、動態連結、方法
    出口等資訊。每一個方法被呼叫直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中從入棧到出
    棧的過程。

  • 本地方法棧(Native Method Stacks),本地方法棧(Native Method Stacks)與虛擬機器棧所發揮
    的作用是非常相似的,其區別不過是虛擬機器棧為虛擬機器執行Java方法(也就是位元組碼)服務,而本
    地方法棧則是為虛擬機器使用到的Native方法服務。
    ###9、物件分配規則

  • 物件優先分配在Eden區,如果Eden區沒有足夠的空間時,虛擬機器執行一次Minor GC。

  • 大物件直接進入老年代(大物件是指需要大量連續記憶體空間的物件)。這樣做的目的是避免在
    Eden區和兩個Survivor區之間發生大量的記憶體拷貝(新生代採用複製演算法收集記憶體)。

  • 長期存活的物件進入老年代。虛擬機器為每個物件定義了一個年齡計數器,如果物件經過了1次
    Minor GC那麼物件會進入Survivor區,之後每經過一次Minor GC那麼物件的年齡加1,知道達到
    閥值物件進入老年區。

  • 動態判斷物件的年齡。如果Survivor區中相同年齡的所有物件大小的總和大於Survivor空間的一
    半,年齡大於或等於該年齡的物件可以直接進入老年代。

  • 空間分配擔保。每次進行Minor GC時,JVM會計算Survivor區移至老年區的物件的平均大小,如
    果這個值大於老年區的剩餘值大小則進行一次Full GC,如果小於檢查HandlePromotionFailure設
    置,如果true則只進行Monitor GC,如果false則進行Full GC。
    ###10、描述一下JVM載入class檔案的原理機制?
    JVM中類的裝載是由類載入器(ClassLoader)和它的子類來實現的,Java中的類載入器是一個重要的
    Java執行時系統元件,它負責在執行時查詢和裝入類檔案中的類。 由於Java的跨平臺性,經過編譯的
    Java源程式並不是一個可執行程式,而是一個或多個類檔案。當Java程式需要使用某個類時,JVM會確
    保這個類已經被載入、連線(驗證、準備和解析)和初始化。類的載入是指把類的.class檔案中的資料
    讀入到記憶體中,通常是建立一個位元組陣列讀入.class檔案,然後產生與所載入類對應的Class物件。載入
    完成後,Class物件還不完整,所以此時的類還不可用。當類被載入後就進入連線階段,這一階段包括
    驗證、準備(為靜態變數分配記憶體並設定預設的初始值)和解析(將符號引用替換為直接引用)三個步
    驟。最後JVM對類進行初始化,包括:1)如果類存在直接的父類並且這個類還沒有被初始化,那麼就先
    初始化父類;2)如果類中存在初始化語句,就依次執行這些初始化語句。 類的載入是由類載入器完成
    的,類載入器包括:根載入器(BootStrap)、擴充套件載入器(Extension)、系統載入器(System)和
    使用者自定義類載入器(java.lang.ClassLoader的子類)。從Java 2(JDK 1.2)開始,類載入過程採取了
    父親委託機制(PDM)。PDM更好的保證了Java平臺的安全性,在該機制中,JVM自帶的Bootstrap是
    根載入器,其他的載入器都有且僅有一個父類載入器。類的載入首先請求父類載入器載入,父類載入器
    無能為力時才由其子類載入器自行載入。JVM不會向Java程式提供對Bootstrap的引用。下面是關於幾個
    類載入器的說明:

  • Bootstrap:一般用原生程式碼實現,負責載入JVM基礎核心類庫(rt.jar);

  • Extension:從java.ext.dirs系統屬性所指定的目錄中載入類庫,它的父載入器是Bootstrap;

  • System:又叫應用類載入器,其父類是Extension。它是應用最廣泛的類載入器。它從環境變數
    classpath或者系統屬性java.class.path所指定的目錄中記載類,是使用者自定義載入器的預設父加
    載器。
    ###11、Java物件建立過程
    1.JVM遇到一條新建物件的指令時首先去檢查這個指令的引數是否能在常量池中定義到一個類的符號引
    用。然後載入這個類(類載入過程在後邊講)
    2.為物件分配記憶體。一種辦法“指標碰撞”、一種辦法“空閒列表”,最終常用的辦法“本地執行緒緩衝分配
    (TLAB)”
    3.將除物件頭外的物件記憶體空間初始化為0
    4.對物件頭進行必要設定
    ###12、類的生命週期
    類的生命週期包括這幾個部分,載入、連線、初始化、使用和解除安裝,其中前三部是類的載入的過程,如
    下圖;
    image.png

  • 載入,查詢並載入類的二進位制資料,在Java堆中也建立一個java.lang.Class類的物件

  • 連線,連線又包含三塊內容:驗證、準備、初始化。 1)驗證,檔案格式、後設資料、位元組碼、符號
    引用驗證; 2)準備,為類的靜態變數分配記憶體,並將其初始化為預設值; 3)解析,把類中的符
    號引用轉換為直接引用

  • 初始化,為類的靜態變數賦予正確的初始值

  • 使用,new出物件程式中使用

  • 解除安裝,執行垃圾回收
    ###13、簡述Java的物件結構
    Java物件由三個部分組成:物件頭、例項資料、對齊填充。
    物件頭由兩部分組成,第一部分儲存物件自身的執行時資料:雜湊碼、GC分代年齡、鎖標識狀態、線
    程持有的鎖、偏向執行緒ID(一般佔32/64 bit)。第二部分是指標型別,指向物件的類後設資料型別(即對
    象代表哪個類)。如果是陣列物件,則物件頭中還有一部分用來記錄陣列長度。
    例項資料用來儲存物件真正的有效資訊(包括父類繼承下來的和自己定義的)
    對齊填充:JVM要求物件起始地址必須是8位元組的整數倍(8位元組對齊)
    ###14、如何判斷物件可以被回收?
    判斷物件是否存活一般有兩種方式:

  • 引用計數:每個物件有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數
    為0時可以回收。此方法簡單,無法解決物件相互迴圈引用的問題。

  • 可達性分析(Reachability Analysis):從GC Roots開始向下搜尋,搜尋所走過的路徑稱為引用
    鏈。當一個物件到GC Roots沒有任何引用鏈相連時,則證明此物件是不可用的,不可達物件。
    ###15、JVM的永久代中會發生垃圾回收麼?
    垃圾回收不會發生在永久代,如果永久代滿了或者是超過了臨界值,會觸發完全垃圾回收(Full GC)。如
    果你仔細檢視垃圾收集器的輸出資訊,就會發現永久代也是被回收的。這就是為什麼正確的永久代大小
    對避免Full GC是非常重要的原因。請參考下Java8:從永久代到後設資料區 (注:Java8中已經移除了永久
    代,新加了一個叫做後設資料區的native記憶體區)
    ###16、垃圾收集演算法
    GC最基礎的演算法有三種: 標記 -清除演算法、複製演算法、標記-壓縮演算法,我們常用的垃圾回收器一般都
    採用分代收集演算法。

  • 標記 -清除演算法,“標記-清除”(Mark-Sweep)演算法,如它的名字一樣,演算法分為“標記”和“清除”兩
    個階段:首先標記出所有需要回收的物件,在標記完成後統一回收掉所有被標記的物件。

  • 複製演算法,“複製”(Copying)的收集演算法,它將可用記憶體按容量劃分為大小相等的兩塊,每次只
    使用其中的一塊。當這一塊的記憶體用完了,就將還存活著的物件複製到另外一塊上面,然後再把已
    使用過的記憶體空間一次清理掉。

  • 標記-壓縮演算法,標記過程仍然與“標記-清除”演算法一樣,但後續步驟不是直接對可回收物件進行清
    理,而是讓所有存活的物件都向一端移動,然後直接清理掉端邊界以外的記憶體

  • 分代收集演算法,“分代收集”(Generational Collection)演算法,把Java堆分為新生代和老年代,這
    樣就可以根據各個年代的特點採用最適當的收集演算法。
    ###17、調優命令有哪些?

  • Sun JDK監控和故障處理命令有jps jstat jmap jhat jstack jinfo

  • jps,JVM Process Status Tool,顯示指定系統內所有的HotSpot虛擬機器程式。

  • jstat,JVM statistics Monitoring是用於監視虛擬機器執行時狀態資訊的命令,它可以顯示出虛擬機器
    程式中的類裝載、記憶體、垃圾收集、JIT編譯等執行資料。

  • jmap,JVM Memory Map命令用於生成heap dump檔案

  • jhat,JVM Heap Analysis Tool命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內建了
    一個微型的HTTP/HTML伺服器,生成dump的分析結果後,可以在瀏覽器中檢視

  • jstack,用於生成java虛擬機器當前時刻的執行緒快照。

  • jinfo,JVM Configuration info 這個命令作用是實時檢視和調整虛擬機器執行引數。
    ###18、調優工具
    常用調優工具分為兩類,jdk自帶監控工具:jconsole和jvisualvm,第三方有:MAT(Memory Analyzer
    Tool)、GChisto。

  • jconsole,Java Monitoring and Management Console是從java5開始,在JDK中自帶的java監控
    和管理控制檯,用於對JVM中記憶體,執行緒和類等的監控

  • jvisualvm,jdk自帶全能工具,可以分析記憶體快照、執行緒快照;監控記憶體變化、GC變化等。

  • MAT,Memory Analyzer Tool,一個基於Eclipse的記憶體分析工具,是一個快速、功能豐富的Java
    heap分析工具,它可以幫助我們查詢記憶體洩漏和減少記憶體消耗

  • GChisto,一款專業分析gc日誌的工具
    ###19、Minor GC與Full GC分別在什麼時候發生?
    新生代記憶體不夠用時候發生MGC也叫YGC,JVM記憶體不夠的時候發生FGC
    ###20、你知道哪些JVM效能調優

  • 設定堆記憶體大小
    -Xmx:堆記憶體最大限制。

  • 設定新生代大小。 新生代不宜太小,否則會有大量物件湧入老年代
    -XX:NewSize:新生代大小
    -XX:NewRatio 新生代和老生代佔比
    -XX:SurvivorRatio:伊甸園空間和倖存者空間的佔比

  • 設定垃圾回收器 年輕代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC

點這裡-》》》》》

相關文章