第二章 內(nèi)存區(qū)域和 OOM內(nèi)存溢出

目錄
一、內(nèi)存區(qū)域
二径玖、內(nèi)存溢出和內(nèi)存泄漏
三痴脾、實(shí)操OutOfMemoryError
四、對(duì)象的創(chuàng)建和對(duì)象的內(nèi)存布局
五梳星、JVM調(diào)參集錦

一赞赖、內(nèi)存區(qū)域

image-20200712120044489.png

線程共享內(nèi)存區(qū):方法區(qū)、堆
線程獨(dú)有內(nèi)存區(qū):虛擬機(jī)棧冤灾、本地方法棧前域、程序計(jì)數(shù)器
注意:線程共享內(nèi)存區(qū)就是我們常要考慮內(nèi)存回收的地方、而線程獨(dú)有內(nèi)存區(qū)是會(huì)隨著線程的執(zhí)行結(jié)束而消亡的韵吨,不需要考慮內(nèi)存回收

1.程序計(jì)數(shù)器(program counter register)

  • 定義:當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器

  • 獨(dú)占線程:程序計(jì)數(shù)器屬于線程獨(dú)占去,每個(gè)線程都有一個(gè)程序計(jì)數(shù)器

  • 字節(jié)碼計(jì)數(shù)器如何工作?

    通過改變程序計(jì)數(shù)器的值來讀取下一條字節(jié)碼指令
    (分支话侄、循環(huán)、異常處理学赛、線程恢復(fù)都依賴計(jì)數(shù)器)

  • java方法:計(jì)數(shù)器記錄的是正在執(zhí)行的字節(jié)碼指令的地址

  • native方法:值為空(undefined)

  • 此內(nèi)存無OOM:此區(qū)域是唯一一個(gè)在jvm規(guī)范中沒有固定任何OutOfMemory情況的區(qū)域

  • 保留字:java中的goto,現(xiàn)在不用,可能以后會(huì)用,暫不開發(fā),防止以后jdk出現(xiàn)新功能的時(shí)候之前的程序全部報(bào)錯(cuò)

2.虛擬機(jī)棧

  • 定義:
    描述的是java方法執(zhí)行的動(dòng)態(tài)內(nèi)存模型,
    線程私有(創(chuàng)建一個(gè)方法就有創(chuàng)建一個(gè)棧幀push,方法調(diào)用執(zhí)行完成,對(duì)應(yīng)的棧幀pop)
    每一個(gè)方法從調(diào)用開始到執(zhí)行完成的過程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧里面從入棧到出棧的過程吞杭。
  • 棧幀定義:存放著局部變量表,操作棧,動(dòng)態(tài)鏈接,方法出口
  1. 局部變量表

    • 定義:基本數(shù)據(jù)類:(boolean,byte,char,short,int,long,float,double)
    • 對(duì)象引用:(reference),可能是引用指針,對(duì)象句柄,對(duì)象相關(guān)的位置,字節(jié)碼指令地址
    • 局部變量表內(nèi)存固定:局部變量表內(nèi)存在編譯的期間完成分配,運(yùn)行期間不會(huì)改變局部變量表的大小
    • 總結(jié):Java的八大基礎(chǔ)數(shù)據(jù)(32位可放下),64位高低兩個(gè)存放,局部的對(duì)象則存放用對(duì)象的引用
  2. 操作數(shù)棧

    • 定義:是棧幀中一個(gè)先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),虛擬機(jī)將這里作為他的工作區(qū),方法區(qū)中進(jìn)行add算數(shù)運(yùn)算或者參數(shù)傳遞是通過操作數(shù)棧
    • 操作數(shù)棧理論獨(dú)立,但大部分虛擬機(jī)會(huì)優(yōu)化,一部分?jǐn)?shù)據(jù)可以實(shí)現(xiàn)棧幀共享,這樣方法調(diào)用,無需額外的參數(shù)復(fù)制傳遞
    • 總結(jié):操作的元素是任意的java數(shù)據(jù)類型,一個(gè)方法剛剛開始的時(shí)候,操作數(shù)棧是空的,操作數(shù)棧運(yùn)行方法是JVM一直在入棧/出棧的過程
  3. 動(dòng)態(tài)鏈接
    每個(gè)棧幀都包含一個(gè)(指向常量池中該棧幀所屬方法)的引用,用來支持動(dòng)態(tài)鏈接的實(shí)現(xiàn),符號(hào)引用(名字)和直接引用(地址)在運(yùn)行時(shí)進(jìn)行解釋和鏈接的過程,稱為動(dòng)態(tài)鏈接

    • 部分符號(hào)引用在類加載階段(解析)的時(shí)候就轉(zhuǎn)化為直接引用,這種轉(zhuǎn)化為靜態(tài)鏈接
    • 部分符號(hào)引用在運(yùn)行期間轉(zhuǎn)化為直接引用,這種轉(zhuǎn)化為動(dòng)態(tài)鏈接
  4. 方法出口:(返回地址)
    正常返回:調(diào)用PC程序計(jì)數(shù)器的地址進(jìn)行返回,即調(diào)用該方法的下一條指令地址
    異常返回:異常處理器表<非棧幀中的>來確定,棧幀一般不會(huì)保存這部分信息

  5. 圖解


    image-20200716065525058.png
  • StackOverflowError:當(dāng)棧深度大于虛擬機(jī)所允許的最大長(zhǎng)度

    Exception in thread "main" java.lang.StackOverflowError

  • OOM:虛擬機(jī)椪到剑可動(dòng)態(tài)擴(kuò)展的情況,無法申請(qǐng)到足夠的物理內(nèi)存,會(huì)報(bào)OOM錯(cuò)誤

3.本地方法棧

(HotSpot不分虛擬機(jī)棧和本地方法棧)
因此對(duì)于HotSpot來說,-Xoss參數(shù)(設(shè)置本地方法棧大小)雖然存在芽狗,但實(shí)際上是無效的绢掰,棧容量只由-Xss .

  • 本地方法棧:為虛擬機(jī)使用到的native方法服務(wù)
  • 虛擬機(jī)棧:為虛擬機(jī)執(zhí)行Java方法(字節(jié)碼)服務(wù)
  • 但本地方法棧并不是用 Java 實(shí)現(xiàn)的,而是由 C 語言實(shí)現(xiàn)的。
  • 何為native方法:

    "A native method is a Java method whose implementation is provided by non-java code."
    1.Native方法就是java調(diào)用非java代碼的接口,這個(gè)接口的實(shí)現(xiàn)不是java寫的
    2.C++中,你可以extern "C"告知c++編譯器調(diào)用c函數(shù)

4.堆內(nèi)存

定義:存放所有對(duì)象實(shí)例,GC垃圾回收器管理最大的區(qū)域,可以處于物理上不連續(xù)的內(nèi)存空間
"不一定"存所有對(duì)象實(shí)例:JIT編譯器優(yōu)化----出現(xiàn)虛擬機(jī)棧上分配

image-20200712150442873.png

  • 新生代(Young Generation):很快就會(huì)被GC回收掉的或者不是特別大的對(duì)象滴劲。

    1.劃分為Eden(伊甸園)和Survivor區(qū)攻晒,最后Survivor由FromSpace和ToSpace組成,三個(gè)區(qū)域默認(rèn)情況下是按照8:1:1分配,也可以手動(dòng)配置。
    2.JVM每次只會(huì)使用Eden區(qū)和一塊Survivor區(qū)來為對(duì)象服務(wù),另一塊Survivor區(qū)域是空的,用于垃圾回收
    3.舉例:
    第一次GC,將Eden+from存活的對(duì)象復(fù)制到to,清空Eden和from(存活對(duì)象小于to的空間)
    第二次GC,虛擬機(jī)使用Eden+to,將存活對(duì)象移到from
    就這樣反復(fù)在from,to循環(huán),復(fù)制過程內(nèi)存不夠使用則向老年代分配擔(dān)保

  • 老年代(Old Generation):
    Tenured Gen
    新生代每一次GC后,都給對(duì)象"+1歲",當(dāng)年齡到達(dá)一定數(shù)量則會(huì)進(jìn)入老年代
    (默認(rèn)15, -XX:MaxTenuringThreshold設(shè)置)
    大的對(duì)象直接進(jìn)入老年代
    (默認(rèn)15, -XX:PretenuringThreshold設(shè)置)
    -XX:PretenureSizeThreshold3M班挖,那么大于3M的對(duì)象就會(huì)直接就進(jìn)入老年代鲁捏。

  • 永久代/持久代(Permanent Generation ):即JVM的方法區(qū)
    存放一些虛擬機(jī)加載的類信息的靜態(tài)文件,更不易被回收

  • TLAB(thread local allocation buffer):分配緩沖區(qū)
    堆內(nèi)存是線程共享的,堆上分配的內(nèi)存需要加鎖,為了提高效率,會(huì)為每個(gè)新建的線程在Eden上分配一塊獨(dú)立空間線程獨(dú)享,在TLAB上不需要加鎖,所有JVM給線程中的對(duì)象分配內(nèi)存會(huì)優(yōu)先使用AB分配緩沖區(qū)

如何創(chuàng)建對(duì)象
對(duì)象分配內(nèi)存 -> 內(nèi)存初始化 -> 對(duì)象初始化 -> 構(gòu)造方法

  • 指針碰撞(雙指針) free區(qū) |正在分配內(nèi)存|已用區(qū)域
  • 空閑列表
    線程安全:TLAB

5.方法區(qū)

  • 定義:用于存儲(chǔ)被虛擬機(jī)加載的(類信息包括常量池),靜態(tài)變量,常量,編譯后的代碼
    • 方法區(qū)是堆的邏輯部分,但是與堆內(nèi)存分開的。
    • 類信息:類的版本,類的全限定名,字段,方法,接口
  • 執(zhí)行類.class的過程
    • 在加載類(加載萧芙、(驗(yàn)證给梅、準(zhǔn)備、解析3步稱為連接)双揪、初始化)
  • 永久代:HotSpot虛擬機(jī)特有的概念,HotSpot 虛擬機(jī)使用永久代來實(shí)現(xiàn)方法區(qū)动羽,
  • 版本的改動(dòng):
    1. JDK1.7的HotSpot:方法區(qū)移除了字符串常量池
    2. JDK1.8的HotSpot:取消了方法區(qū),用元空間(Meta Space)代替
  • 元空間的大小參數(shù)
    JDK1.7及以前(初始和最大值):-XX:PermSize -XX:MaxPermSize
    JDK1.8(初始和最大值):-XX:MetaSpaceSize -XX:MaxMetaSpaceSize

6.元空間

  • 定義:元空間的本質(zhì)和永久代類似,都是對(duì)JVM中方法區(qū)的實(shí)現(xiàn),最大的區(qū)別是元空間使用的是本地內(nèi)存
  • 為什么要用元空間代替永久代?
    1. 性能和OOM問題:字符串在永久代,容易出現(xiàn)性能問題和內(nèi)存溢出問題
    2. 空間大小導(dǎo)致溢出:類及方法的信息比較難確定大小,永久代的內(nèi)存大小指定困難,小-->永久代溢出(方法區(qū)太小), 大-->老年代溢出(堆內(nèi)存太小)
    3. GC回收效率低

7.運(yùn)行時(shí)常量池

  • 定義:方法區(qū)的一部分(.class文件)中的常量池(存放編譯時(shí)的引用)會(huì)在類加載后存放到方法區(qū)的運(yùn)行時(shí)常量池
  • 幼兒園化:java文件編譯成class文件,常量池的字面量和符號(hào)引用只是個(gè)名字而已,還沒指向?qū)?yīng)的內(nèi)存地址,類加載的時(shí)候會(huì)把這些字面量和符號(hào)引用放入運(yùn)行時(shí)常量池(runtime constant pool)并指向?qū)?yīng)的內(nèi)存地址
  • 動(dòng)態(tài)性:String.intern()方法調(diào)用時(shí)可以將常量放入到運(yùn)行時(shí)常量池中
  • OOM:常量池?zé)o法從方法區(qū)獲得內(nèi)存,也會(huì)拋異常OutOfMemoryError
  • JDK6中,不推薦大量使用intern方法渔期,因?yàn)檫@個(gè)版本字符串緩存在永久代中运吓,這個(gè)空間是有限了,除了FullGC之外不會(huì)被清除疯趟,大量的緩存在這容易OutOfMemoryError拘哨。之后的版本把字符串放入了堆中,避免了永久代被擠滿迅办。
  • JDK1.7:字符串常量池從方法區(qū)移至堆內(nèi)存中
  • JDK1.8:方法區(qū)的移除,運(yùn)行時(shí)常量池移至元空間中(Meta Space)
  • 避免在一個(gè)系統(tǒng)中產(chǎn)生大量的String對(duì)象宅静,引入了字符串常量池。


    image-20200713094221170.png

8.直接內(nèi)存

  • 定義:直接內(nèi)存并不是虛擬機(jī)運(yùn)行時(shí)的一部分,這部分卻頻繁的使用,在JDK1.4中加入NIO(New Input/Output)類,使用Native函數(shù)可以直接分配堆外地址,存儲(chǔ)在Java堆里面的DirectByteBuffer對(duì)象作為這塊堆外內(nèi)存的引用
  • 好處:在一些場(chǎng)景中可以顯著提高性能,避免了在堆內(nèi)存和堆外內(nèi)存中來回拷貝數(shù)據(jù)

二站欺、內(nèi)存溢出和內(nèi)存泄漏

內(nèi)存溢出

內(nèi)存溢出:JVM在申請(qǐng)內(nèi)存的時(shí)候,因?yàn)闆]有足夠的內(nèi)存而引發(fā)的錯(cuò)誤OOM

1.堆溢出

  • 原因:
    1. 堆內(nèi)存過小或者內(nèi)存泄漏
    2. 大對(duì)象(大數(shù)組)分配內(nèi)存
    3. 頻繁的調(diào)用String.intern()方法,1.7(不包括)以后字符串的常量池在堆內(nèi)存中
    4. GC回收效率低,98%時(shí)間回收不到%2的空間
  • 常用參數(shù):-Xms -Xmx(堆內(nèi)存初始容量和最大容量)

    -Xms512m

2.棧溢出

  • 官方:

    如果線程<u>請(qǐng)求的棧深度</u>大于虛擬機(jī)所允許的最大深度姨夹,將拋出StackOverflowError異常。
    如果虛擬機(jī)在<u>擴(kuò)展棧</u>時(shí)無法申請(qǐng)到足夠的內(nèi)存空間矾策,則拋出OutOfMemoryError異常磷账。

  • OutOfMemory(多線程):每個(gè)線程都有對(duì)應(yīng)的棧幀與之對(duì)應(yīng),棧內(nèi)存過大或者線程數(shù)過多都會(huì)造成OOM

    1. 棧內(nèi)存過大

      每個(gè)線程分配到的棧容量大,可以建立的線程數(shù)就少,需要建立新線程就容易把剩下的內(nèi)存耗盡

    2. 線程數(shù)過多

      棧內(nèi)存有限,隨著線程數(shù)的增加,棧內(nèi)存的空間就慢慢減少

  • StackOverflowError單線程:往往發(fā)生于單線程的錯(cuò)誤地?zé)o限遞歸,當(dāng)線程所請(qǐng)求的棧最大深度大于虛擬機(jī)所允許的最大深度(-Xss),拋出StackOverflowError

    1. 單線程下的棧內(nèi)存減少
    2. 新建本地變量,使得線程棧幀的局部變量表變大
  • 常用參數(shù)

    -Xss(棧容量大小,可理解為棧幀深度)

3.方法區(qū)溢出

  • 定義:方法區(qū)存儲(chǔ)的是JVM加載的類信息,靜態(tài)變量,常量,JIT編譯后的代碼,經(jīng)常動(dòng)態(tài)生成大量class的應(yīng)用中,要注意會(huì)不會(huì)出現(xiàn)OOM
  • 出現(xiàn)得到情況
    1. 大量的JSP,JSP第一次訪問時(shí),JSP引擎會(huì)將JSP轉(zhuǎn)換編譯成Class,加入內(nèi)存
    2. JDK1.7以前(不包括1.7)的HotSpot頻繁的使用String.intern().那時(shí)的字符串常量池還在方法區(qū)
    3. 存在大量反射的場(chǎng)景,也會(huì)把class加載進(jìn)內(nèi)存
  • 常用參數(shù):

    1.7及其之前,通過-XX:PermSize -XX:PermSizeMax:限制方法區(qū)的大小
    1.8:-XX:MetaSpaceSize -XX:MaxSpaceSize:元空間初始與最大容量

4.直接內(nèi)存溢出

  • 定義:在JDK1.4中加入NIO(New Input/Output)類,使用Native函數(shù)可以直接分配堆外地址,存儲(chǔ)在Java堆里面的DirectByteBuffer對(duì)象作為這塊堆外內(nèi)存的引用
  • 直接內(nèi)存只能Full GC清理回收不像新生代和老年代,發(fā)現(xiàn)空間不足就通知GC回收
  • Minor GC Major GC Full GC
    從年輕代空間(包括 Eden 和 Survivor 區(qū)域)回收內(nèi)存被稱為 Minor GC。 Major GC 是清理永久代贾虽。Full GC 是清理整個(gè)堆空間—包括年輕代和永久代逃糟。(年輕代收集不能把對(duì)象放進(jìn)永久代時(shí),就會(huì)觸發(fā)一次完全收集Major-GC)

5.內(nèi)存泄漏

Memory Leak,程序在申請(qǐng)內(nèi)存后,無法釋放已申請(qǐng)的內(nèi)存空間(一個(gè)對(duì)象不再被需要了蓬豁,可是收集器卻無法將它回收) , 一次內(nèi)存泄漏危害很小,但是長(zhǎng)期堆積后很嚴(yán)重,無論有多少內(nèi)存,最終會(huì)被耗光,memory leak最終導(dǎo)致----> OOM

三绰咽、實(shí)操OutOfMemoryError

--------------------------------------進(jìn)階1-------------------------------------
--------------------jvm運(yùn)行時(shí)中添加arguments參數(shù)-------------------
Run as -> Run Configuration -> arguments(VM arguments) -> 添加以下內(nèi)容

-XX:+HeapDumpOnOutOfMemoryError -Xms20m -Xmx20m

再次運(yùn)行生成java_pid8374.hprof的快照文件

---------------------------------------進(jìn)階2----------------------------------------
--------------------MAT工具分析出現(xiàn)OOM的原因--------------------------
將java_pid8374.hprof導(dǎo)入MAT中 -> 首頁有圓形圖分析 -> open dominator tree for entire heap(樹結(jié)構(gòu)查看堆結(jié)構(gòu))
shallowed heap:自身對(duì)象占用空間
retained heap:自身對(duì)象及其引用占用空間


image-20200711110902546.png

參數(shù)解釋:
-XX:+HeapDumpOnOutOfMemoryError -----拍攝OOM溢出的快照+配合MAT工具查看使用
-Xms20m ------初始的Heap的大小。
-Xmx20m --------Xmx最大Heap的大小地粪。
-Xss規(guī)定了每個(gè)線程棧的大小取募。一般情況下256K是足夠了。影響了此進(jìn)程中并發(fā)線程數(shù)大小蟆技。

--------------------------------------------------進(jìn)階3--------------------------------------------
------------------------------自帶的jconsole程序(實(shí)際是lib/tools.jar)--------------------------
cmd ->(配置java環(huán)境變量的情況下) -> jconsole(出現(xiàn)小程序頁面) -> 本地進(jìn)程(sun.tools.jconsole.JConsole)

四玩敏、對(duì)象的創(chuàng)建和對(duì)象的內(nèi)存布局

對(duì)象的創(chuàng)建

  • 對(duì)象創(chuàng)建過程

    1. new 類
    2. new 的參數(shù)在常量池中(方法區(qū)或者M(jìn)eta Space)定位符號(hào)引用
    3. 沒有引用,則進(jìn)行類加載,鏈接,初始化
    4. 在堆中給對(duì)象分配內(nèi)存空間
    5. 內(nèi)存初始化=0(不包括對(duì)象頭)
    6. 調(diào)用對(duì)象的init方法
  • 總結(jié)

    • 對(duì)象分配內(nèi)存 -> 內(nèi)存初始化 -> 對(duì)象初始化 -> 構(gòu)造方法
    • 指針碰撞(雙指針) free區(qū) |正在分配內(nèi)存|已用區(qū)域(GC器有相應(yīng)的劃分內(nèi)存區(qū)域的功能)
    • 空閑列表
      線程安全:TLAB

對(duì)象的內(nèi)存布局

image-20200724221104887.png

image-20200812155310278.png
image-20200724221141087.png
  • 對(duì)象頭Header
    • 自身運(yùn)行數(shù)據(jù)(Mark Word)
      • 哈希值hashcode / 偏向線程ID + epoch(偏向鎖的時(shí)間戳)
      • GC分代年齡
      • 是否偏向,鎖狀態(tài)標(biāo)志
    • 類型指針:JVM通過這個(gè)指針確定這個(gè)對(duì)象是哪個(gè)類的實(shí)例
  • 實(shí)例數(shù)據(jù)InstanceData
    • 對(duì)象真正存儲(chǔ)的有效信息,定義各種類型的數(shù)據(jù),包括父類繼承下來的
  • 對(duì)齊填充Padding
    • 相當(dāng)于占位符,HotSpot VM的自動(dòng)內(nèi)存管理系統(tǒng)要求對(duì)象的起始地址必須是8字節(jié)的整數(shù)倍,so當(dāng)實(shí)例數(shù)據(jù)部分沒有對(duì)齊時(shí),會(huì)以對(duì)齊填充來補(bǔ)全(對(duì)象頭部部分正好8字節(jié)的1或者2倍)
  • 對(duì)象的訪問定位
    通過棧的引用去操作堆中的對(duì)象,引用訪問堆中對(duì)象有兩種方式
    • 句柄:Java堆中劃分一塊內(nèi)存作為句柄池,棧的(引用reference)存放的是對(duì)象的句柄信息,句柄包含了對(duì)象實(shí)例數(shù)據(jù)和類型數(shù)據(jù)兩塊地址信息,
      好處:reference中存儲(chǔ)的是穩(wěn)定的句柄地址,對(duì)象在移動(dòng)時(shí)(GC非常的常見)只會(huì)改變句柄的實(shí)例數(shù)據(jù)指針,reference本身不需要修改
    • 直接指針:堆對(duì)象需考慮如何放置訪問類型數(shù)據(jù)的相關(guān)信息,reference中直接存儲(chǔ)對(duì)象地址信息
      好處:速度更快,節(jié)省了一次指針定位的開銷
      Hotspot 使用的是直接指針的方式訪問對(duì)象斗忌。

五、JVM調(diào)參集錦

基礎(chǔ)

  • 打印gc信息

    -verbose:gc -XX:+PrintGCDetails

  • xms xmx xss xmn

    1. -Xms 為jvm啟動(dòng)時(shí)分配的內(nèi)存旺聚,比如-Xms200m织阳,表示分配200M,默認(rèn)為物理內(nèi)存的1/64
    2. -Xmx 為jvm運(yùn)行過程中分配的最大內(nèi)存,比如-Xms500m砰粹,表示jvm進(jìn)程最多只能夠占用500M內(nèi)存,默認(rèn)為物理內(nèi)存的1/4
    3. -Xss (虛擬機(jī)棧)為jvm啟動(dòng)的設(shè)置每個(gè)線程的堆棧大小唧躲,默認(rèn)JDK1.4中是256K,JDK1.5+中是1M
      在相同物理內(nèi)存下伸眶,減小這個(gè)值能生成更多的線程惊窖。
    4. -Xmn4g:設(shè)置年輕代大小為4G.
      -Xmn 堆內(nèi)新生代的大小。通過這個(gè)值也可以得到老生代的大欣逶簟:-Xmx減去-Xmn
  • 非堆內(nèi)存分配:

    -XX:NewRatio=4
    設(shè)置年輕代(包括Eden和兩個(gè)Survivor區(qū))與年老代的比值(除去持久代)界酒。設(shè)置為4,則年輕代與年老代所占比值為1:4嘴秸,年輕代占整個(gè)堆棧的1/5毁欣。
    -XX:SurvivorRatio=4
    設(shè)置年輕代中Eden區(qū)與Survivor區(qū)的大小比值。設(shè)置為4岳掐,則兩個(gè)Survivor區(qū)與一個(gè)Eden區(qū)的比值為2:4凭疮,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/6。(4:1:1)串述。
    -XX:MaxPermSize=16m 設(shè)置持久代大小為16m执解。
    -XX:MaxTenuringThreshold=0
    設(shè)置垃圾最大年齡。大于這個(gè)年齡的都會(huì)進(jìn)入老年代區(qū)纲酗。如果設(shè)置為0的話衰腌,則年輕代對(duì)象不經(jīng)過Survivor區(qū),直接進(jìn)入年老代觅赊。對(duì)于年老代比較多的應(yīng)用右蕊,可以提高效率。如果將此值設(shè)置為一個(gè)較大值吮螺,則年輕代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制饶囚,這樣可以增加對(duì)象再年輕代的存活時(shí)間,增加在年輕代即被回收的概論鸠补。

進(jìn)階

  • 修改收集器

    串行收集器DefNew:是使用-XX:+UseSerialGC(新生代萝风,老年代都使用串行回收收集器)
    并行收集器ParNew:是使用-XX:+UseParNewGC(新生代使用并行收集器,老年代使用串行收集器)
    并行收集器PSYoungGen:是使用-XX:+UseParallelOldGC(新生代紫岩,老年代都使用并行回收收集器)或者-XX:+UseParallelGC(新生代使用并行回收收集器闹丐,老年代使用串行收集器)
    并發(fā)收集器CMS: -XX:+UseConcMarkSweepGC(新生代使用并行收集器,老年代使用CMS)被因。
    并發(fā)收集器garbage-first heap:是使用-XX:+UseG1GC(G1收集器)

  • 大對(duì)象直接進(jìn)入老年代

    why?如果放在年輕代的Eden,GC頻繁,采用復(fù)制算法導(dǎo)致經(jīng)常移動(dòng)大對(duì)象,這會(huì)消耗資源
    -XX:PretenureSizeThreshold=6M 超過6M直接分配到進(jìn)老年代

  • 存活年齡多大的對(duì)象進(jìn)入老年代

    -XX:MaxTenuringThreshold 15 設(shè)置的是年齡閾值卿拴,默認(rèn)15(對(duì)象被復(fù)制的次數(shù))

  • 允許分配擔(dān)保:Eden區(qū)域從老年代借空間(相當(dāng)于貸款)
    JVM繼續(xù)檢查老年代最大的可用連續(xù)空間是否大于歷次晉升到老年代的對(duì)象的平均大小,如果大于梨与,則正常進(jìn)行一次YGC堕花,盡管有風(fēng)險(xiǎn)(因?yàn)榕袛嗟氖瞧骄笮。锌赡苓@次的晉升對(duì)象比平均值大很多)粥鞋;
    如果小于缘挽,或者HandlePromotionFailure設(shè)置不允許空間分配擔(dān)保,這時(shí)要進(jìn)行一次FGC呻粹。

    -XX:+HandlePromotionFailure 允許分配擔(dān)保

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壕曼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子等浊,更是在濱河造成了極大的恐慌腮郊,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筹燕,死亡現(xiàn)場(chǎng)離奇詭異轧飞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)撒踪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門过咬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人制妄,你說我怎么就攤上這事掸绞。” “怎么了耕捞?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵衔掸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我砸脊,道長(zhǎng)具篇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任凌埂,我火速辦了婚禮驱显,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞳抓。我一直安慰自己埃疫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布孩哑。 她就那樣靜靜地躺著栓霜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪横蜒。 梳的紋絲不亂的頭發(fā)上胳蛮,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天销凑,我揣著相機(jī)與錄音,去河邊找鬼仅炊。 笑死斗幼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抚垄。 我是一名探鬼主播蜕窿,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼呆馁!你這毒婦竟也來了桐经?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤浙滤,失蹤者是張志新(化名)和其女友劉穎阴挣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓷叫,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屯吊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摹菠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盒卸。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖次氨,靈堂內(nèi)的尸體忽然破棺而出蔽介,到底是詐尸還是另有隱情,我是刑警寧澤煮寡,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布虹蓄,位于F島的核電站,受9級(jí)特大地震影響幸撕,放射性物質(zhì)發(fā)生泄漏薇组。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一坐儿、第九天 我趴在偏房一處隱蔽的房頂上張望律胀。 院中可真熱鬧,春花似錦貌矿、人聲如沸炭菌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽黑低。三九已至,卻和暖如春酌毡,著一層夾襖步出監(jiān)牢的瞬間克握,已是汗流浹背蕾管。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菩暗,地道東北人娇掏。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像勋眯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子下梢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容