JVM 常用參數(shù)設(shè)置積累
# 堆的初始值芙扎,默認(rèn)物理內(nèi)存的1/64
-Xms:
# 堆的最大值星岗,默認(rèn)物理內(nèi)存的1/4
-Xmx:
# 年輕代大小「在整個堆內(nèi)存大小確定的情況下,增大年輕代將會減小年老代戒洼,反之亦然俏橘。此值關(guān)系到JVM垃圾回收,對系統(tǒng)性能影響較大圈浇,官方推薦配置為整個堆大小的3/8」
-Xmn:
# 設(shè)置年輕代初始值為 1024 M
-XX:NewSize=1024
# 設(shè)置年輕代最大值為 1024 M
-XX:MaxNewSize=1024m
# 設(shè)置線程棧大小寥掐,設(shè)置越小,說明一個線程棧里面能分配的棧幀數(shù)就越少汉额,但對于 JVM 來講曹仗,能開啟的線程數(shù)就越多;
-Xss128k
# 方法區(qū)大小設(shè)置「jdk1.8 之后使用元空間替換了方法區(qū)蠕搜,也使用了其他命令」
-XX:MaxPermSize
# 元空間大小設(shè)置
-XX:MetaspaceSize
-XX:MaxMetaspaceSize
# 設(shè)置大對象的大小怎茫,如果對象超過設(shè)置大小會直接進(jìn)入老年代,不會進(jìn)入年輕代「只在 Serial 和ParNew兩個收集 器下有效」
-XX:PretenureSizeThreshold=1000000
# 設(shè)定對象晉升到老年代的年齡閾值「設(shè)定能經(jīng)歷 10 次拷貝妓灌,對象則晉升至老年代」
-XX:MaxTenuringThreshold=10
# jdk1.8 默認(rèn)設(shè)置了下述參數(shù)轨蛤,設(shè)置該參數(shù),就會在每次 minor gc 之前看看老年代的可用內(nèi)存大小虫埂,是否大于之前每一次 minor gc 后進(jìn)入老年代的對象的平均大小祥山,如果小于則那么就會觸發(fā)一次 Full gc
-XX:-HandlePromotionFailure
JVM 排查問題命令積累
# 查詢實(shí)例個數(shù)和占用空間大小
jmap -histo pid
# 導(dǎo)出堆內(nèi)存信息
jmap -dump:format=b,file=test.hprof pid
# 查找死鎖,打印出線程的狀態(tài)
jstack pid
# 查看當(dāng)前運(yùn)行 java 應(yīng)用的擴(kuò)展參數(shù)
jinfo pid
# 查看內(nèi)存中各個部分的使用情況「eden掉伏、survivor缝呕、old」
jstat -gc pid
# 堆內(nèi)存統(tǒng)計(jì)
jstat -gccapacity pid
# 新生代內(nèi)存統(tǒng)計(jì)
jstat -gcnewcapacity pid
# 新生代垃圾回收統(tǒng)計(jì)
jstat -gcnew pid
# 老年代內(nèi)存統(tǒng)計(jì)
jstat -gcoldcapacity pid
# 老年代垃圾回收統(tǒng)計(jì)
jstat -gcold pid
# 元數(shù)據(jù)空間統(tǒng)計(jì)
//加入Java開發(fā)交流君樣:593142328一起吹水聊天
jstat -gcmetacapacity pid
# 總結(jié)垃圾回收統(tǒng)計(jì)
jstat -gcutil pid
JVM 的運(yùn)行模式有三種:
- 解釋模式「-Xint」:只使用解釋器,執(zhí)行一行字節(jié)碼就編譯一次機(jī)器碼「不會去緩存」斧散;
- 優(yōu)點(diǎn):啟動塊供常;
- 缺點(diǎn):整體執(zhí)行相比編譯模式慢;
- 編譯模式「-Xcomp」:只使用編譯器鸡捐,現(xiàn)將所有的字節(jié)碼文件一次性編譯為機(jī)器碼栈暇,然后一次性去執(zhí)行所有的機(jī)器碼;
- 優(yōu)點(diǎn):好處是執(zhí)行快箍镜;
- 缺點(diǎn):啟動比解釋模式慢源祈;
- 混合模式:依舊采用解釋模式執(zhí)行代碼,但是對于一些“熱點(diǎn)”代碼采用編譯模式執(zhí)行色迂,JVM 一般采用混合模式執(zhí)行代碼香缺;
- 優(yōu)點(diǎn):相比解釋模式,執(zhí)行會快脚草,相比編譯模式赫悄,啟動會快;
針對混合模式馏慨,JVM 有對應(yīng)的技術(shù)去實(shí)現(xiàn)埂淮,比如 JIT,也就是即時(shí)編輯技術(shù)写隶。
JVM 內(nèi)存分配與回收
- jvm 內(nèi)存區(qū)域圖
堆
- 堆內(nèi)內(nèi)存:堆內(nèi)內(nèi)存 = 年輕代 + 老年代 + 持久代『jdk1.8 之后沒有持久代』
- 優(yōu)點(diǎn):
- 缺點(diǎn):
- 堆外內(nèi)存:把內(nèi)存對象分配在 Java 虛擬機(jī)的堆以外的內(nèi)存「比如:java.nio.DirectByteBuffer」
- 優(yōu)點(diǎn):
- 減少了垃圾回收機(jī)制(GC 會暫停其他的工作)倔撞;
- 加快了復(fù)制的速度「堆內(nèi)在flush到遠(yuǎn)程時(shí), 會先復(fù)制到直接內(nèi)存(非堆內(nèi)存), 然后再發(fā)送,而堆外內(nèi)存(本身就是物理機(jī)內(nèi)存)幾乎省略了該步驟」慕趴。
- 缺點(diǎn):
- 內(nèi)存難以控制「使用了堆外內(nèi)存就間接失去了JVM管理內(nèi)存的可行性痪蝇,改由自己來管理,當(dāng)發(fā)生內(nèi)存溢出時(shí)排查起來非常困難」冕房。
年輕代
- 伊甸區(qū):
survivor from 區(qū)
:survivor to 區(qū) = 8:1:1
伊甸區(qū)
- 大部分對象都在這里誕生
- 當(dāng)Eden區(qū)滿時(shí), 依然存活的對象將被復(fù)制到
Survivor
區(qū), 當(dāng)一個Survivor
區(qū)滿時(shí), 此區(qū)的存活對象將被復(fù)制到另外一個Survivor
區(qū)
survivor 區(qū)
-
survivor from
區(qū) -
survivor to
區(qū)
老年代
方法區(qū)/元空間
- 在 jdk1.8 之后取消了方法區(qū)躏啰,命名為元空間
線程棧
什么場景下對象會進(jìn)入老年代
- 即將存儲的大對象在
eden
區(qū)域是發(fā)現(xiàn)存儲不下「就算Minor gc
后還是存儲不下」; - 長期存活下來的對象耙册;
-
Minor gc
后存活的對象Survivor
區(qū)放不下给僵;
什么是老年代空間分配擔(dān)保機(jī)制
年輕代每次 minor gc 之前 JVM 都會計(jì)算下老年代剩余可用空間如果這個可用空間小于年輕代里現(xiàn)有的所有對象大小之和(包括垃圾對象)就會看一個 “-XX:-HandlePromotionFailure”(jdk1.8 默認(rèn)就設(shè)置了)的參數(shù)是否設(shè)置了,如果有這個參數(shù)详拙,就會看看老年代的可用內(nèi)存大小帝际,是否大于之前每一次 minor gc 后進(jìn)入老年代的對象的平均大小。
如果上一步結(jié)果是小于或者之前說的參數(shù)沒有設(shè)置饶辙,那么就會觸發(fā)一次 Full gc蹲诀,對老年代和年輕代一起回收一次垃圾,如果回收完還是沒有足夠空間存放新的對象就會發(fā)生 OOM弃揽,當(dāng)然脯爪,如果 minor gc 之后剩余存活的需要挪動到老年代的對象大小還是大于老年代可用空間,那么也會觸發(fā) full gc矿微,full gc
完之后如果還是沒用空間放 minor gc 之后的存活對象痕慢,則也會發(fā)生 “OOM”。
觸發(fā) full gc 的時(shí)機(jī)
- 調(diào)用System.gc()冷冗;
- 老生代內(nèi)存不足的時(shí)候守屉;
- 即將要放進(jìn)老年代的對象過大,需要進(jìn)行老年代回收蒿辙;「和第二種類似」
- 老年代空間分配擔(dān)保機(jī)制中有可能觸發(fā)拇泛;「也就是老年代空間分配擔(dān)保失敗」
- 執(zhí)行 jmap -histo:live 或者 jmap -dump:live 的時(shí)候;
如何判斷對象可以被回收
1. 引用計(jì)數(shù)法
給對象添加一個引用計(jì)數(shù)器思灌,沒增加一個地方引用它俺叭,計(jì)數(shù)器就加一,減少一個泰偿,計(jì)數(shù)器就減一熄守,但是解決不了循環(huán)引用的問題「會導(dǎo)致內(nèi)存泄露」,主流的虛擬機(jī)都沒有使用這個。
2. 可達(dá)性分析
通過一系列的稱為 GC Roots 的對象作為起點(diǎn)裕照,從這些節(jié)點(diǎn)開始向下搜索攒发,找到的對象都標(biāo)記為非垃圾對象,其余未標(biāo)記的對象都是垃圾對象晋南。
GC Roots 根節(jié)點(diǎn):線程棧的本地變量惠猿、靜態(tài)變量、本地方法棧的變量等等负间。
具體操作:從gc root根往下搜索偶妖,然后三色標(biāo)記,黑灰白政溃,剛開始是白色趾访,如果搜索到A節(jié)點(diǎn),A節(jié)點(diǎn)的子節(jié)點(diǎn)還沒被搜索董虱,則A節(jié)點(diǎn)是灰色扼鞋,A節(jié)點(diǎn)包括子節(jié)點(diǎn)全部搜索完畢標(biāo)記為黑色,到最后白色的就回收了
3. 依據(jù)引用類型
java的引用類型一般分為四種:強(qiáng)引用空扎、軟引用藏鹊、弱引用、虛引用转锈。
- 強(qiáng)引用
普通的變量引用
public static Person person = new Person();
- 軟引用
將對象用SoftReference
軟引用類型的對象包裹盘寡,正常情況不會被回收,但是GC做完后發(fā)現(xiàn)釋放不出空間存放新的對象撮慨,則會把這些軟引用的對象回收掉竿痰。軟引用可用來實(shí)現(xiàn)內(nèi)存敏感的高速緩存。【白嫖資料】
public static SoftReference<Person> person = new SoftReference<Person>(new Person());
- 弱引用
將對象用 WeakReference 軟引用類型的對象包裹砌溺,弱引用跟沒引用差不多影涉,GC 會直接回收掉,很少用规伐。
public static WeakReference<Person> person = new WeakReference<Person>(new Person());
- 虛引用
虛引用也稱為幽靈引用或者幻影引用蟹倾,是最弱的一種引用關(guān)系,幾乎不用猖闪。
一個對象是否有虛引用的存在鲜棠,完全不會對其生存時(shí)間構(gòu)成影響,也無法通過虛引用來獲取一個對象的實(shí)例培慌。為一個對象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個對象被收集器回收時(shí)收到一個系統(tǒng)通知豁陆。虛引用和弱引用對關(guān)聯(lián)對象的回收都不會產(chǎn)生影響,如果只有虛引用活著弱引用關(guān)聯(lián)著對象吵护,那么這個對象就會被回收盒音。它們的不同之處在于弱引用的get方法表鳍,虛引用的get方法始終返回null,弱引用可以使用ReferenceQueue祥诽,虛引用必須配合ReferenceQueue使用譬圣。
jdk中直接內(nèi)存的回收就用到虛引用,由于jvm自動內(nèi)存管理的范圍是堆內(nèi)存原押,而直接內(nèi)存是在堆內(nèi)存之外(其實(shí)是內(nèi)存映射文件胁镐,自行去理解虛擬內(nèi)存空間的相關(guān)概念)偎血,所以直接內(nèi)存的分配和回收都是有Unsafe類去操作诸衔,java在申請一塊直接內(nèi)存之后,會在堆內(nèi)存分配一個對象保存這個堆外內(nèi)存的引用颇玷,這個對象被垃圾收集器管理笨农,一旦這個對象被回收,相應(yīng)的用戶線程會收到通知并對直接內(nèi)存進(jìn)行清理工作帖渠。
4. 通過 finalize() 方法最終判定對象是否存活
即使在可達(dá)性分析算法中不可達(dá)的對象谒亦,也并非是“非死不可”的,這時(shí)候它們暫時(shí)處于“緩刑”階段空郊,要真正宣告一個對象死亡份招,至少要經(jīng)歷再次標(biāo)記過程。標(biāo)記的前提是對象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒有與 GC Roots 相連接的引用鏈狞甚。
- 第一次標(biāo)記并進(jìn)行一次篩選锁摔。
篩選的條件是此對象是否有必要執(zhí)行 finalize() 方法。當(dāng)對象沒有覆蓋 finalize 方法哼审,對象將直接被回收谐腰。 - 第二次標(biāo)記
如果這個對象覆蓋了 finalize 方法,finalize 方法是對象脫逃死亡命運(yùn)的最后一次機(jī)會涩盾,如果對象要在 finalize() 中成功拯救自己十气,只要重新與引用鏈上的任何的一個對象建立關(guān)聯(lián)即可,譬如把自己賦值給某個類變量或?qū)ο蟮某蓡T變量春霍,那在第二次標(biāo)記時(shí)它將移除出“即將回收”的集合砸西。如果對象這時(shí)候還沒逃脫,那基本上它就真的被回收了址儒。
垃圾回收算法
1芹枷、標(biāo)記-清除算法
分為兩個階段,即標(biāo)記和清除离福,首先會標(biāo)記所有需要被回收的對象杖狼,在標(biāo)記完成后統(tǒng)一對已經(jīng)標(biāo)記的對象進(jìn)行回收,是最基礎(chǔ)的收集算法妖爷。
- 優(yōu)點(diǎn)
- 實(shí)現(xiàn)簡單
- 缺點(diǎn)
- 內(nèi)存碎片化
- 效率不高
- 使用場景:主流虛擬機(jī)不使用
2蝶涩、標(biāo)記-整理算法「也叫標(biāo)記-壓縮算法」
針對老年代進(jìn)行回收的一種算法理朋,標(biāo)記的過程和『標(biāo)記-清除算法』一樣,只是在清除完成后绿聘,會將還存活的對象朝著一個方向移動嗽上,然后固定的清理靠近邊界的對象。
- 優(yōu)點(diǎn)
- 解決了碎片化
- 缺點(diǎn)
- 效率不高
- 移動了對象地址熄攘,需要更新對象的引用
- 使用場景:用于老年代垃圾回收
3兽愤、復(fù)制算法「比標(biāo)記清理和標(biāo)記整理快 10 倍以上」
能解決「標(biāo)記-清理算法」帶來碎片化問題,復(fù)制算法首先將內(nèi)存分為大小相同的兩塊挪圾,每次只使用其中的一塊浅萧,但這一塊被使用完后「或者是沒法提供所需的連續(xù)長度的內(nèi)存」,就會將這一塊的內(nèi)存復(fù)制到另一塊去哲思,然后再一次性將這塊的內(nèi)存空間全部清理掉洼畅。
- 優(yōu)點(diǎn)
- 解決了碎片化
- 效率高
- 缺點(diǎn)
- 內(nèi)存使用率不高
- 使用場景:用于年輕代垃圾回收
4、分代回收算法
這種算法不是新鮮的算法棚赔,而是針對不同的內(nèi)存分區(qū)帝簇,采用不同的回收算法,比如在新生代中靠益,每次收集都會有大量對象(近 99%)死去丧肴,所以可以選擇復(fù)制算法,只需要付出少量對象的復(fù)制成本就可以完成每次垃圾收集胧后。而老年代的對象存活幾率是比較高的芋浮,而且沒有額外的空間對它進(jìn)行分配擔(dān)保「老年代多是大對象绩卤,很可能是需要連續(xù)內(nèi)存地址的對象」途样,所以我們必須選擇「標(biāo)記清除算法」或「標(biāo)記整理算法」進(jìn)行垃圾收集。
垃圾收集器「回收算法的具體實(shí)現(xiàn)」
1濒憋、Serial 收集器「-XX:+UseSerialGC -XX:+UseSerialOldGC」
新生代采用復(fù)制算法何暇,老年代采用標(biāo)記-整理算法
Serial(串行)收集器是最基本、歷史最悠久的垃圾收集器了凛驮。是一個單線程收集器了裆站。它的 “單線程” 的意義不僅僅意味著它只會使用一條垃圾收集線程去完成垃圾收集工作,更重要的是它在進(jìn)行垃圾收集工作的時(shí)候必須暫停其他所有的工作線程「也就是應(yīng)用程序線程」黔夭,直到它收集結(jié)束宏胯。
Serial 收集器執(zhí)行過程
- 優(yōu)點(diǎn)
- 沒有多線程交互,單線程實(shí)現(xiàn)簡單本姥;
- 相比其他單線程收集器肩袍,效率最高「當(dāng)然是比不上多線程收集器」;
- 缺點(diǎn):
- STW 時(shí)間長婚惫,用戶體驗(yàn)不好
- 使用場景:
一種用途是在 JDK1.5 以及以前的版本中與 Parallel Scavenge 收集器搭配使用氛赐,另一種用途是作為 CMS 收集器的后備方案魂爪。
2、ParNew 收集器「-XX:+UseParNewGC」
新生代采用復(fù)制算法艰管,老年代采用標(biāo)記-整理算法
ParNew 收集器其實(shí)就是 Serial 收集器的多線程版本滓侍,除了使用多線程進(jìn)行垃圾收集外,其余行為(控制參數(shù)牲芋、收集算法撩笆、回收策略等等)和 Serial 收集器完全一樣。默認(rèn)的收集線程數(shù)跟 CPU 核數(shù)相同缸浦,當(dāng)然也可以用參數(shù)(-XX:ParallelGCThreads)指定收集線程數(shù)夕冲,但是一般不推薦修改。
ParNew 收集器執(zhí)行過程
[圖片上傳失敗...(image-e41a95-1625644454829)]
- 優(yōu)點(diǎn):
- 相比 Serial 效率高
- 缺點(diǎn):
- 實(shí)現(xiàn)稍復(fù)雜
- 使用場景:
3餐济、Parallel 收集器「-XX:+UseParallelGC(年輕代) -XX:+UseParallelOldGC(老年代)」
新生代采用復(fù)制算法耘擂,老年代采用標(biāo)記-整理算法
Parallel Scavenge 收集器關(guān)注點(diǎn)是吞吐量(高效率的利用CPU)。CMS 等垃圾收集器的關(guān)注點(diǎn)更多的是用戶線程的停頓時(shí)間(提高用戶體驗(yàn))絮姆。所謂吞吐量就是 CPU 中用于運(yùn)行用戶代碼的時(shí)間與 CPU 總消耗時(shí)間的比值。 Parallel Scavenge 收集器提供了很多參數(shù)供用戶找到最合適的停頓時(shí)間或最大吞吐量秩霍,如果對于收集器運(yùn)作不太了解的話篙悯,可以選擇把內(nèi)存管理優(yōu)化交給虛擬機(jī)去完成也是一個不錯的選擇。
[圖片上傳失敗...(image-e0df1-1625644454829)]
優(yōu)點(diǎn):
缺點(diǎn):
使用場景:
Parallel 收集器執(zhí)行過程
4铃绒、CMS 收集器「-XX:+UseConcMarkSweepGC(old)」
新生代采用復(fù)制算法鸽照,老年代采用標(biāo)記-整理算法
CMS(Concurrent Mark Sweep)以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。它非常符合在注重用戶體驗(yàn)的應(yīng)用上使用颠悬,它是 HotSpot 虛擬機(jī)第一款真正意義上的并發(fā)收集器矮燎,它第一次實(shí)現(xiàn)了讓垃圾收集線程與用戶線程(基本上)同時(shí)工作。
CMS 收集器執(zhí)行過程
初始標(biāo)記-》并發(fā)標(biāo)記-》重新標(biāo)記-》并發(fā)清理-》并發(fā)重置
其中只有『初始標(biāo)記』不能和用戶線程并發(fā)赔癌,其他的四個是可以的诞外。
[圖片上傳失敗...(image-2bb354-1625644454829)]
- 優(yōu)點(diǎn):
- 并發(fā)收集、低停頓灾票;
- 吞吐量高峡谊;
- 缺點(diǎn):
- 對 CPU 資源敏感(會和服務(wù)搶資源);
- 無法處理浮動垃圾(即在并發(fā)清理階段又產(chǎn)生垃圾刊苍,這種浮動垃圾只能等到下一次 GC 再清理了)既们;
- 它使用的回收算法“標(biāo)記-清除”算法會導(dǎo)致收集結(jié)束時(shí)會有大量空間碎片產(chǎn)生,當(dāng)然通過參數(shù) -XX:+UseCMSCompactAtFullCollection 可以讓 jvm 在執(zhí)行完標(biāo)記清除后再做整理正什;
- 執(zhí)行過程中的不確定性啥纸,會存在上一次垃圾回收還沒執(zhí)行完,然后垃圾回收又被觸發(fā)的情況婴氮,特別是在并發(fā)標(biāo)記和并發(fā)清理階段會出現(xiàn)斯棒,一邊回收馒索,系統(tǒng)一邊運(yùn)行,也許沒回收完就再次觸發(fā) full gc名船,也就是“concurrent mode failure”绰上,此時(shí)會進(jìn)入 stop the world,使用 serial old 垃圾收集器來回收渠驼;
- 使用場景
注重用戶體驗(yàn)的系統(tǒng)蜈块,低延時(shí)。
何為[ concurrent mode failure 錯誤
5迷扇、G1 收集器「-XX:+UseG1GC」
一款面向服務(wù)器的垃圾收集器百揭,主要針對配備多顆處理器及大容量內(nèi)存的機(jī)器,以極高概率滿足 GC 停頓時(shí)間要求的同時(shí)蜓席,還具備高吞吐量性能特征器一。會預(yù)測的停頓的時(shí)間,以及一些抉擇厨内,比如 200ms 回收 10MB 和 50ms 回收 20MB 兩種選擇祈秕,會選擇第二種,用以達(dá)到有限時(shí)間內(nèi)最大的回收效率雏胃;
優(yōu)點(diǎn):
缺點(diǎn):
使用場景:
逃逸分析
public void test() {
Person person = new Person();
}
上面的代碼请毛,會經(jīng)歷如下幾個步驟:
- 加載 Person.class 到內(nèi)存上;
- 在棧中開辟一段空間瞭亮,用于 test 方法的入棧方仿,然后在 test 方法的棧空間分配一個變量 p统翩;
- 在堆內(nèi)存中創(chuàng)建一塊區(qū)域空間仙蚜,分配內(nèi)存地址「new 關(guān)鍵字的作用」;
- 對空間的屬性空間分配厂汗,默認(rèn)初始化委粉;
- 構(gòu)造函數(shù)初始化;
- 將分配的地址賦值給變量 p面徽,即 p 指向了剛剛劃分并且初始化好的堆地址艳丛;
按照上面的步驟,每個對象的分配趟紊,對象會直接分配在堆上氮双,但如果需要分配的對象非常多,并且生命周期都比較短霎匈,比如在某個循環(huán)中一直 new 某一個類的對象戴差,并且創(chuàng)建的對象不會作為返回值『或者是返回值的一部分 』,返回給調(diào)用者铛嘱,那么這些數(shù)量多且生命周期短的對象暖释,將會占用較多的堆空間袭厂,這些被占用的會由 GC 定時(shí)去清理,但如果有一種手段球匕,盡量的讓這些對象都存儲在棧里面纹磺,也就是方法棧,這些對象的銷毀會隨著方法的出棧而消亡亮曹,就不再需要 GC 去耗費(fèi)寶貴的時(shí)間和資源去回收堆內(nèi)存了橄杨,STW 的時(shí)間自然也會短,GC 的次數(shù)也會少照卦,這種手段就是逃逸分析式矫,在 JDK8 中逃逸分析是默認(rèn)開啟。
『但一種手段的出現(xiàn)役耕,肯定是有利也有弊采转,開啟逃逸分析也會耗費(fèi)時(shí)間和資源,就需要我們自己去測試分析瞬痘,手上的項(xiàng)目是否合適故慈,不能保證逃逸分析的性能收益必定高于它的消耗』
逃逸分析的分類
- 方法逃逸
- 線程逃逸
方法逃逸
當(dāng)一個對象在方法里面被定義后,它可能被外部方法所引用图云,例如作為調(diào)用參數(shù)傳遞到其它方法中惯悠。
線程逃逸
這個對象甚至可能被其它線程訪問到,例如賦值給類變量或可以在其它線程中訪問的實(shí)例變量竣况。
逃逸分析總結(jié)
當(dāng)一個對象,在其生命周期內(nèi)筒严,被其他對象所持有丹泉,那么就會發(fā)生逃逸。
** 最后鸭蛙,祝大家早日學(xué)有所成摹恨,拿到滿意offer,快速升職加薪娶视,走上人生巔峰晒哄。**
可以的話請給我一個三連支持一下我喲??????【白嫖資料】