JAVA線上常見問題排查CPU飆高內(nèi)存打滿排查

首先執(zhí)行最簡單的四步驟隘竭,再逐步檢查

{PID} 為實際Java在服務(wù)器中的進(jìn)程ID一般為服務(wù)器排名第一的那個Java進(jìn)程
首先前提是:先獲取占用最高的Java進(jìn)程西饵,然后再找出Java進(jìn)程中CPU/內(nèi)存占用最高的線程

詳細(xì)可參考 快速成為Java故障排查高手
1.控制臺執(zhí)行 jstack {PID} > log.text 將生成的堆棧數(shù)據(jù)生成至日志中方便查看
2.轉(zhuǎn)換線程ID控制臺執(zhí)行 printf "%x\n" {TID} 注意:TID為線程ID
3.定位cpu占用線程控制臺執(zhí)行 jstack {PID}|grep {tid} -A 30
4.將2步驟獲得的tid去log.text中搜索,查看當(dāng)前線程是否在異常堆棧日志中
/opt/java8/bin/jstack

Usage:
    jstack [-l] <pid>
        (to connect to running process) 連接活動線程
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process) 連接阻塞線程
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file) 連接dump的文件
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server) 連接遠(yuǎn)程服務(wù)器

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

詳細(xì)各項指標(biāo)排查如下:

CPU

是系統(tǒng)重要監(jiān)控指標(biāo)开泽,能夠分析系統(tǒng)的整體運行狀況抓于。監(jiān)控一般包括運行隊列尽爆、CPU 使用率和上下文切換等

top 命令是 Linux 下常用的 CPU 性能分析工具 , 能夠?qū)崟r顯示系統(tǒng)中各個進(jìn)程的資源占用狀況 , 常用于服務(wù)端性能分析。

top 命令顯示了各個進(jìn)程從高到低排序 CPU 使用情況 螟够。

其中 Load Average 顯示最近 1 分鐘灾梦、5 分鐘和 15 分鐘的系統(tǒng)平均負(fù)載峡钓,上圖各值為 0.0.4,0.09若河,0.13
我們一般會關(guān)注 CPU 使用率最高的進(jìn)程能岩,正常情況下就是我們的應(yīng)用主進(jìn)程。

PID : 進(jìn)程 id
USER : 進(jìn)程所有者
PR : 進(jìn)程優(yōu)先級
NI : nice 值萧福。負(fù)值表示高優(yōu)先級拉鹃,正值表示低優(yōu)先級
VIRT : 進(jìn)程使用的虛擬內(nèi)存總量,單位 kb鲫忍。VIRT=SWAP+RES
RES : 進(jìn)程使用的膏燕、未被換出的物理內(nèi)存大小,單位 kb悟民。RES=CODE+DATA
SHR : 共享內(nèi)存大小坝辫,單位 kb
S : 進(jìn)程狀態(tài)。D= 不可中斷的睡眠狀態(tài) R= 運行 S= 睡眠 T= 跟蹤 / 停止 Z= 僵尸進(jìn)程
%CPU : 上次更新到現(xiàn)在的 CPU 時間占用百分比
%MEM : 進(jìn)程使用的物理內(nèi)存百分比
TIME+ : 進(jìn)程使用的 CPU 時間總計射亏,單位 1/100 秒
COMMAND : 進(jìn)程名稱

內(nèi)存

內(nèi)存是排查線上問題的重要參考依據(jù)近忙,內(nèi)存問題很多時候是引起 CPU 使用率較高的見解因素。
系統(tǒng)內(nèi)存:free 是顯示的當(dāng)前內(nèi)存的使用 ,-m 的意思是 M 字節(jié)來顯示內(nèi)容智润。

free -m
 total 內(nèi)存總數(shù): 3790M
 used 已經(jīng)使用的內(nèi)存數(shù): 1880M
 free 空閑的內(nèi)存數(shù): 118M
 shared 當(dāng)前已經(jīng)廢棄不用 , 總是 0
 buffers Buffer 緩存內(nèi)存數(shù): 1792M

磁盤

df -h

網(wǎng)絡(luò)

dstat 命令可以集成了 vmstat及舍、iostat、netstat 等等工具能完成的任務(wù)做鹰。
 dstat -c  cpu 情況
    -d 磁盤讀寫
        -n 網(wǎng)絡(luò)狀況
        -l 顯示系統(tǒng)負(fù)載
        -m 顯示形同內(nèi)存狀況
        -p 顯示系統(tǒng)進(jìn)程信息
        -r 顯示系統(tǒng) IO 情況

vmstat:
vmstat 2 10 -t
vmstat 是 Virtual Meomory Statistics(虛擬內(nèi)存統(tǒng)計)的縮寫 , 是實時系統(tǒng)監(jiān)控工具击纬。該命令通過使用 knlist 子程序和 /dev/kmen 偽設(shè)備驅(qū)動器訪問這些數(shù)據(jù),輸出信息直接打印在屏幕钾麸。
使用 vmstat 2 10 -t 命令更振,查看 io 的情況 (第一個參數(shù)是采樣的時間間隔數(shù)單位是秒,第二個參數(shù)是采樣的次數(shù))

定位排查問題時最為常用命令包括:jps(進(jìn)程)饭尝、jmap(內(nèi)存)肯腕、jstack(線程)、jinfo(參數(shù)) 等
jps: 查詢當(dāng)前機器所有 JAVA 進(jìn)程信息
jmap: 輸出某個 java 進(jìn)程內(nèi)存情況 (如:產(chǎn)生那些對象及數(shù)量等)
jstack: 打印某個 Java 線程的線程棧信息
jinfo: 用于查看 jvm 的配置參數(shù)

JAVA線上排查常用命令

jmap命令

jmap -heap pid 輸出當(dāng)前進(jìn)程 JVM 堆新生代钥平、老年代实撒、持久代等請情況,GC 使用算法等信息
jmap -histo:live {pid} | head -n 10 輸出當(dāng)前進(jìn)程內(nèi)存中所有對象包含的大小
jmap -dump:format=b,file=/usr/local/logs/gc/dump.hprof {pid} 以二進(jìn)制輸出檔當(dāng)前內(nèi)存的堆情況涉瘾,
然后可以導(dǎo)入 MAT 等工具進(jìn)行

1知态、 jmap -heap pid

輸出當(dāng)前進(jìn)程JVM堆新生代、老年代立叛、持久代等情況负敏,GC使用的算法等信息。


2秘蛇、jmap -histo:live {pid} | head -n 10 輸出當(dāng)前進(jìn)程內(nèi)存中所有對象包含的大小

輸出當(dāng)前進(jìn)程內(nèi)存中所有對象實例數(shù) (instances) 和大小 (bytes), 如果某個業(yè)務(wù)對象
實例數(shù)和大小存在異常情況其做,可能存在內(nèi)存泄露或者業(yè)務(wù)設(shè)計方面存在不合理之處顶考。


3.jmap -dump:

命令如下必選先創(chuàng)建文件夾,不會自動生成:

mkdir logs
jmap -dump:format=b,file=/tmp/logs/dump.hprof {pid}

-dump:formate=b,file={path}
以二進(jìn)制輸出當(dāng)前內(nèi)存的堆情況至相應(yīng)的文件妖泄,然后使用 MAT 等內(nèi)存分析工具深入分析當(dāng)前內(nèi)存情況

也可以通過JVM參數(shù)配置OOM時自動dump當(dāng)前內(nèi)存鏡像文件驹沿。
-XX:+HeapDumpOnOutOfMemoryError 和-XX:HeapDumpPath
所代表的含義就是當(dāng)程序出現(xiàn)OutofMemory時,將會在相應(yīng)的目錄下生成一份dump文件蹈胡,
而如果不指定選項-XX:HeapDumpPath則在當(dāng)前目錄下生成dump文件

確保應(yīng)用發(fā)生 OOM 時 JVM 能夠保存并 dump 出當(dāng)前的內(nèi)存鏡像渊季。
當(dāng)然,如果你決定手動 dump 內(nèi)存時罚渐,dump 操作占據(jù)一定 CPU 時間片梭域、內(nèi)存資源、磁盤資源等搅轿,因此會帶來一定的系統(tǒng)資源消耗影響

此外病涨,dump 的文件可能比較大 , 一般我們可以考慮使用 zip 命令對文件進(jìn)行壓縮處理,這樣在下載文件時能減少帶寬的開銷璧坟。
下載 dump 文件完成之后既穆,由于 dump 文件較大可將 dump 文件備份至制定位置或者直接刪除,以釋放磁盤在這塊的空間占用雀鹃。

4.dump日志分析:

MAT(Memory Analyzer Tool)幻工,一個基于 Eclipse 的內(nèi)存分析工具,是一個快速黎茎、功能豐富的 JAVA heap 分析工具囊颅,它可以幫助我們查找內(nèi)存泄漏和減少內(nèi)存消耗。
使用內(nèi)存分析工具從眾多的對象中進(jìn)行分析傅瞻,快速的計算出在內(nèi)存中對象的占用大小踢代,看看是誰阻止了垃圾收集器的回收工作,并可以通過報表直觀的查看到可能造成這種結(jié)果的對象嗅骄。
具體可以參考:Java內(nèi)存分析工具M(jìn)AT(Memory Analyzer Tool)安裝使用實例 : https://blog.csdn.net/jin_kwok/article/details/80326088基于Java內(nèi)存dump文件分析解決內(nèi)存泄漏問題 : http://www.reibang.com/p/2cf7169ba1c4

5.jstack命令

printf '%x\n' tid --> 10 進(jìn)制至 16 進(jìn)制線程 ID(navtive 線程) %d 10 進(jìn)制
jstack pid | grep tid -C 30 --color ps -mp 8278 -o THREAD,tid,time | head -n 40
某 Java 進(jìn)程 CPU 占用率高胳挎,我們想要定位到其中 CPU 占用率最高的線程

(1) 先利用top命令找到CPU占用高的進(jìn)程pid
也可以通過ps -ef | grep 應(yīng)用名 來快速定位自己應(yīng)用的pid


顯示pid:25311
(2) 利用 top 命令可以查出占 CPU 最高的線程 pid (先找到該pid 29080下所有的線程數(shù)據(jù))


假設(shè)第一個就是占用最高可以看到占用cpu資源最高的為25311
(3) 占用率最高的線程 ID 為25311,將其轉(zhuǎn)換為 16 進(jìn)制形式 (因為 java native 線程以 16 進(jìn)制形式輸出)
printf '%x\n' 25311

(4) 利用 jstack 打印出 java 線程調(diào)用棧信息
jstack 25311 | grep '62df' -A 50 --color
最后打印的信息就是實際的信息
更多內(nèi)容也可以參考:
如何使用jstack分析線程狀態(tài) : http://www.reibang.com/p/6690f7e92f27
通過jstack與jmap分析一次線上故障: https://www.cnblogs.com/kingszelda/p/9034191.html

6.jinfo命令

jinfo可以用來查看正在運行的java運用程序的擴展參數(shù)溺森。
查看pid對應(yīng)的JVM參數(shù)慕爬,可以到
http://login.perfma.com
校驗參數(shù)的正確性
jinfo -flags pid


拿到Command line后面的配置參數(shù)到perfma中驗證查詢:這里使用默認(rèn)

7.jstat命令

jstat顯示GC執(zhí)行的情況
jstat -gc 25311 2000
即會每2秒一次顯示進(jìn)程號為25311 的java進(jìn)成的GC情況


說明:
S0C、S1C屏积、S0U医窿、S1U:Survivor 0/1區(qū)容量(Capacity)和使用量(Used)
EC、EU:Eden區(qū)容量和使用量
OC炊林、OU:年老代容量和使用量
PC姥卢、PU:永久代容量和使用量
YGC、YGT:年輕代GC次數(shù)和GC耗時
FGC铛铁、FGCT:Full GC次數(shù)和Full GC耗時
GCT:GC總耗時

顯示內(nèi)容說明如下(部分結(jié)果是通過其他其他參數(shù)顯示的隔显,暫不說明):
S0C:年輕代中第一個survivor(幸存區(qū))的容量 (字節(jié))
S1C:年輕代中第二個survivor(幸存區(qū))的容量 (字節(jié))
S0U:年輕代中第一個survivor(幸存區(qū))目前已使用空間 (字節(jié))
S1U:年輕代中第二個survivor(幸存區(qū))目前已使用空間 (字節(jié))
EC:年輕代中Eden(伊甸園)的容量 (字節(jié))
EU:年輕代中Eden(伊甸園)目前已使用空間 (字節(jié))
OC:Old代的容量 (字節(jié))
OU:Old代目前已使用空間 (字節(jié))
PC:Perm(持久代)的容量 (字節(jié))
PU:Perm(持久代)目前已使用空間 (字節(jié))
YGC:從應(yīng)用程序啟動到采樣時年輕代中g(shù)c次數(shù)
YGCT:從應(yīng)用程序啟動到采樣時年輕代中g(shù)c所用時間(s)
FGC:從應(yīng)用程序啟動到采樣時old代(全gc)gc次數(shù)
FGCT:從應(yīng)用程序啟動到采樣時old代(全gc)gc所用時間(s)
GCT:從應(yīng)用程序啟動到采樣時gc用的總時間(s)

8.案例分析:

CPU 使用率高問題定位
利用 top -Hp 6814 輸出進(jìn)程 ID 為 6814 的所有線程 CPU 使用率情況,發(fā)現(xiàn)某個線程使用率比較高饵逐,有些異常括眠。

printf '%x\n' 2304     #輸出線程 ID 的 16 進(jìn)制
jstack pid | grep '0x900' -C 30 --color

輸出的日志表明該線程一直處于與 mysql I/O 狀態(tài):



利用 jmap -dump:format=b,file=/usr/local/logs/gc/dump.hprof {pid} 以二進(jìn)制輸出檔當(dāng)前內(nèi)存的堆情況,然后可以導(dǎo)入 MAT 等工具進(jìn)行分析倍权。


如下圖所示掷豺,點擊 MAT 的支配樹可以發(fā)現(xiàn)存在某個超大對象數(shù)組


經(jīng)過分析發(fā)現(xiàn)數(shù)組中每一個對象都是核心業(yè)務(wù)對象,我們的業(yè)務(wù)系統(tǒng)有一個定時任務(wù)線程會訪問數(shù)據(jù)庫某張業(yè)務(wù)表的所有記錄
然后加載至內(nèi)存然后進(jìn)行處理因此內(nèi)存吃緊薄声,導(dǎo)致 CPU 突然飆升当船。發(fā)現(xiàn)該問題后,已對該方案進(jìn)行重新設(shè)計
jmap -dump:format=b,file=/usr/local/logs/dump.hprof {pid}

  1. GC 日志分析
    GC 日志詳細(xì)分析
    Java 虛擬機 GC 日志是用于定位問題重要的日志信息默辨,頻繁的 GC 將導(dǎo)致應(yīng)用吞吐量下降德频、響應(yīng)時間增加,甚至導(dǎo)致服務(wù)不可用缩幸。
    -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/usr/local/gc/gc.log -XX:+UseConcMarkSweepGC

我們可以在 java 應(yīng)用的啟動參數(shù)中增加 -XX:+PrintGCDetails 可以輸出 GC 的詳細(xì)日志壹置,例外還可以增加其他的輔助參數(shù),如-Xloggc 制定 GC 日志文件地址表谊。如果你的應(yīng)用還沒有開啟該參數(shù) , 下次重啟時請加入該參數(shù)钞护。

上圖為線上某應(yīng)用在平穩(wěn)運行狀態(tài)下的 GC 日志截圖

例子假設(shè)情況講解:
 [2021-12-29T08:25:19.753+0800: 73143.256] : 自JVM啟動73143.256秒時發(fā)生本次GC
[ParNew: 556782K->1200K(629120K), 0.0135760 secs] : 
對新生代進(jìn)行的GC,使用ParNew收集器爆办,556782K是新生代回收前的大小,1200K是新生代回收后大小,
556782K是當(dāng)前新生代分配的內(nèi)存總大小, 0.0135760 secs表示本次新生代回收耗時 0.0135760秒

[825452K->266673K(2027264K), 0.0140300 secs]:825452K是回收堆內(nèi)存大小,
266673K是回收堆之后內(nèi)存大小难咕,2027264K是當(dāng)前堆內(nèi)存總大小,0.0140300 secs表示本次回收共耗時0.0140300秒
[Times: user=0.02 sys=0.00, real=0.02 secs] : 用戶態(tài)耗時0.02秒,系統(tǒng)態(tài)耗時0.00,實際耗時0.02秒

無論是 minor GC 或者是 Full GC, 我們主要關(guān)注 GC 回收實時耗時 , 如 real=0.02secs, 即 stop the world 時間,
如果該時間過長距辆,則嚴(yán)重影響應(yīng)用性能,說明系統(tǒng)存在問題余佃,需要優(yōu)化,同時動態(tài)調(diào)整新生代和老年代的配比

回首示例解讀

以其中一行為例來解讀下日志信息:


[GC (Allocation Failure) [ParNew: 367523K->1293K(410432K), 0.0023988 secs] 
522739K->156516K(1322496K), 0.0025301 secs] [Times: user=0.04 sys=0.00, real=0.01 secs]

表明進(jìn)行了一次垃圾回收跨算,前面沒有Full修飾咙冗,表明這是一次Minor GC ,注意它不表示只GC新生代
并且現(xiàn)有的不管是新生代還是老年代都會STW。

Allocation Failure:
表明本次引起GC的原因是因為在年輕代中沒有足夠的空間能夠存儲新的數(shù)據(jù)了漂彤。

ParNew:表明本次GC發(fā)生在年輕代并且使用的是ParNew垃圾收集器雾消。ParNew是一個Serial收集器的多線程版本,會使用多個CPU和線程完成垃圾收集工作(默認(rèn)使用的線程數(shù)和CPU數(shù)相同挫望,可以使用-XX:ParallelGCThreads參數(shù)限制)立润。該收集器采用復(fù)制算法回收內(nèi)存,期間會停止其他工作線程媳板,即Stop The World桑腮。

367523K->1293K(410432K):單位是KB
三個參數(shù)分別為:
GC前該內(nèi)存區(qū)域(這里是年輕代)使用容量,GC后該內(nèi)存區(qū)域使用容量蛉幸,該內(nèi)存區(qū)域總?cè)萘俊?/p>

0.0023988 secs:
該內(nèi)存區(qū)域GC耗時破讨,單位是秒

522739K->156516K(1322496K):
三個參數(shù)分別為:堆區(qū)垃圾回收前的大小丛晦,堆區(qū)垃圾回收后的大小,堆區(qū)總大小提陶。

[Times: user=0.04 sys=0.00, real=0.01 secs]:
分別表示用戶態(tài)耗時烫沙,內(nèi)核態(tài)耗時和總耗時

分析下可以得出結(jié)論:
該次GC新生代減少了367523-1293=366239K
Heap區(qū)總共減少了522739-156516=366223K
366239 – 366223 =16K,說明該次共有16K內(nèi)存從年輕代移到了老年代隙笆,可以看出來數(shù)量并不多锌蓄,說明都是生命周期短的對象,只是這種對象有很多撑柔。

我們需要的是盡量避免Full GC的發(fā)生瘸爽,讓對象盡可能的在年輕代就回收掉,所以這里可以稍微增加一點年輕代的大小铅忿,讓那17K的數(shù)據(jù)也保存在年輕代中剪决。

GC時,用什么方法判斷哪些對象是需要回收:
1.引用計數(shù)法(已經(jīng)不用了)
2.可達(dá)性分析法
前一種簡而言之就是給對象添加一個引用計數(shù)器檀训,有其他地方引用時這個計數(shù)器+1昼捍,引用失效時-1,為0時就可以刪除掉了肢扯。但是它不能解決循環(huán)引用的問題妒茬,所以一般使用的都是后一種算法。
可達(dá)性分析法的基本思路就是通過一系列名為GC Roots的對象作為起始點蔚晨,從這些節(jié)點開始向下搜索乍钻,搜索所走過的路徑稱為引用鏈(Reference Chain),當(dāng)一個對象到GC Roots沒有任何引用鏈相連時铭腕,則證明此對象是不可用的银择,那就可以回收掉了。
GC Roots一般都是些堆外指向堆內(nèi)的引用累舷,例如:

1.JVM棧中引用的對象
2.方法區(qū)中靜態(tài)屬性引用的對象
3.方法區(qū)中常量引用的對象
4.本地方法棧中引用的對象
以CMS為例浩考,補充一些知識點介紹:
復(fù)制算法介紹:
因為新生代對象生命周期一般很短,現(xiàn)在一般將該內(nèi)存區(qū)域劃分為三塊部分被盈,一塊大的叫Eden,兩塊小的叫Survivor析孽。他們之間的比例一般為8:1:1。

使用的時候只使用Eden + 一塊Survivor只怎。用Eden區(qū)用滿時會進(jìn)行一次minor gc袜瞬,將存活下面的對象復(fù)制到另外一塊Survivor上。如果另一塊Survivor放不下(對應(yīng)虛擬機參數(shù)為 XX:TargetSurvivorRatio身堡,默認(rèn)50邓尤,即50%),對象直接進(jìn)入老年代。
(使用CMS時汞扎,默認(rèn)的新生代收集器是ParNew)(有時新生代GC時季稳,需要找到老年代中引用的新生代對象,這個時候會用到一種叫“卡表”的技術(shù)澈魄,避免老年代的全表掃描景鼠,具體怎么操作的暫時還不知道……)
Survivor區(qū)的意義:如果沒有survivor,Eden每進(jìn)行一次minor gc,存活的對象就會進(jìn)入老年代一忱,老年代很快被填滿就會進(jìn)入major gc。由于老年代空間一般很大谭确,所以進(jìn)行一次gc耗時要長的多帘营!尤其是頻繁進(jìn)行full GC,對程序的響應(yīng)有很大的影響逐哈,俗稱STW Survivor存在就是減少被送到老年代的對象芬迄,進(jìn)而減少Full gc的發(fā)生。默認(rèn)設(shè)置是經(jīng)歷了15次minor gc還在新生代中存活的對象才會被送到老年代昂秃。
為什么要有兩個Survivor:主要是為了解決內(nèi)存碎片化和效率問題禀梳。如果只有一個Survivor時,每觸發(fā)一次minor gc都會有數(shù)據(jù)從Eden放到Survivor肠骆,一直這樣循環(huán)下去算途。注意的是,Survivor區(qū)也會進(jìn)行垃圾回收蚀腿,這樣就會出現(xiàn)內(nèi)存碎片化問題嘴瓤。碎片化會導(dǎo)致堆中可能沒有足夠大的連續(xù)空間存放一個大對象,影響程序性能莉钙。如果有兩塊Survivor就能將剩余對象集中到其中一塊Survivor上廓脆,避免碎片問題

Minor GC和Full GC的區(qū)別以及觸發(fā)條件:

Minor GC

對于復(fù)制算法來說,當(dāng)年輕代Eden區(qū)域滿的時候會觸發(fā)一次Minor GC磁玉,將Eden和From Survivor的對象復(fù)制到另外一塊To Survivor上停忿。
注意:如果某個對象存活的時間超過一定Minor gc次數(shù)會直接進(jìn)入老年代,不在分配到To Survivor上(默認(rèn)15次蚊伞,對應(yīng)虛擬機參數(shù) -XX:+MaxTenuringThreshold)席赂。

Full GC

用于清理整個堆空間。它的觸發(fā)條件主要有以下幾種:
顯式調(diào)用System.gc方法(建議JVM觸發(fā))时迫。
方法區(qū)空間不足(JDK8及之后不會有這種情況了氧枣,詳見下文)
老年代空間不足,引起Full GC别垮。這種情況比較復(fù)雜便监,有以下幾種:
1 大對象直接進(jìn)入老年代引起,由-XX:PretenureSizeThreshold參數(shù)定義
2 Minor GC時,經(jīng)歷過多次Minor GC仍存在的對象進(jìn)入老年代烧董。上面提過毁靶,由-XX:MaxTenuringThreashold參數(shù)定義
3 Minor GC時,動態(tài)對象年齡判定機制會將對象提前轉(zhuǎn)移老年代逊移。年齡從小到大進(jìn)行累加预吆,當(dāng)加入某個年齡段后,累加和超過survivor區(qū)域 * -XX:TargetSurvivorRatio的時候胳泉,從這個年齡段往上的年齡的對象進(jìn)入老年代
4 Minor GC時拐叉,Eden和From Space區(qū)向To Space區(qū)復(fù)制時,大于To Space區(qū)可用內(nèi)存扇商,會直接把對象轉(zhuǎn)移到老年代
JVM的空間分配擔(dān)保機制可能會觸發(fā)Full GC:
在進(jìn)行Minor GC之前凤瘦,JVM的空間擔(dān)保分配機制可能會觸發(fā)3.2、3.3和3.4發(fā)生案铺,即觸發(fā)一次Full GC蔬芥。
空間擔(dān)保分配是指在發(fā)生Minor GC之前,虛擬機會檢查老年代最大可用的連續(xù)空間是否大于新生代所有對象的總空間控汉。
如果大于笔诵,則此次Minor GC是安全的。
如果小于姑子,則虛擬機會查看HandlePromotionFailure設(shè)置值是否允許擔(dān)保失敗乎婿。如果HandlePromotionFailure=true,那么會繼續(xù)檢查老年代最大可用連續(xù)空間是否大于歷次晉升到老年代的對象的平均大小街佑,如果大于次酌,則嘗試進(jìn)行一次Minor GC,但這次Minor GC依然是有風(fēng)險的舆乔,失敗后會重新發(fā)起一次Full gc岳服;如果小于或者HandlePromotionFailure=false,則改為直接進(jìn)行一次Full GC希俩。
所有才會說一次Full GC很有可能是由一次Minor GC觸發(fā)的吊宋。

PS:JDK8中HotSpot為什么要取消永久代?
JDK8取消了永久代,新增了一個叫元空間(Metaspace)的區(qū)域颜武,對應(yīng)的還是JVM規(guī)范中的方法區(qū)(主要存放一些class和元數(shù)據(jù)的信息)意狠。區(qū)別在于元空間使用的并不是JVM中的內(nèi)存刽脖,而是使用本地內(nèi)存假勿。
而這么做的原因大致有以下幾點:
1肆糕、字符串存在永久代中,容易出現(xiàn)性能問題和內(nèi)存溢出篙议。
2唾糯、類及方法的信息等比較難確定其大小怠硼,因此對于永久代的大小指定比較困難,太小容易出現(xiàn)永久代溢出移怯,太大則容易導(dǎo)致老年代溢出香璃。
3、永久代會為 GC 帶來不必要的復(fù)雜度舟误,并且回收效率偏低葡秒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嵌溢,隨后出現(xiàn)的幾起案子眯牧,更是在濱河造成了極大的恐慌,老刑警劉巖赖草,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件学少,死亡現(xiàn)場離奇詭異,居然都是意外死亡疚顷,警方通過查閱死者的電腦和手機旱易,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門禁偎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腿堤,“玉大人,你說我怎么就攤上這事如暖“侍矗” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵盒至,是天一觀的道長酗洒。 經(jīng)常有香客問我,道長枷遂,這世上最難降的妖魔是什么樱衷? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮酒唉,結(jié)果婚禮上矩桂,老公的妹妹穿的比我還像新娘。我一直安慰自己痪伦,他們只是感情好侄榴,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著网沾,像睡著了一般癞蚕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辉哥,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天桦山,我揣著相機與錄音,去河邊找鬼。 笑死度苔,一個胖子當(dāng)著我的面吹牛匆篓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寇窑,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸦概,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了甩骏?” 一聲冷哼從身側(cè)響起窗市,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饮笛,沒想到半個月后咨察,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡福青,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年摄狱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片无午。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡媒役,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宪迟,到底是詐尸還是另有隱情酣衷,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布次泽,位于F島的核電站穿仪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏意荤。R本人自食惡果不足惜啊片,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望玖像。 院中可真熱鬧紫谷,春花似錦、人聲如沸御铃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽上真。三九已至咬腋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間睡互,已是汗流浹背根竿。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工陵像, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寇壳。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓醒颖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壳炎。 傳聞我的和親對象是個殘疾皇子泞歉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

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