摘要:概述又是一次因?yàn)榫€上報(bào)警機(jī)制開啟的排查問題之旅。的常見使用場(chǎng)景有分析哪些方法調(diào)用,獲取其調(diào)用棧接口性能差,分析耗時(shí)情況當(dāng)出現(xiàn)異常時(shí),分析方法的運(yùn)行時(shí)參數(shù)線上有一個(gè)大對(duì)象,查看其內(nèi)容安裝使用依賴于,首先要安裝好并配置的環(huán)境變量。
概述
又是一次因?yàn)榫€上報(bào)警機(jī)制開啟的排查問題之旅。某日,釘釘機(jī)器人瘋狂報(bào)警:
接著就是申請(qǐng)機(jī)器權(quán)限去排查問題,既然是頻繁Full GC,那我們排查問題的思路就應(yīng)該是找到引起Full GC的原因。引起頻繁Full GC的常見原因有這么幾點(diǎn):
堆外內(nèi)存達(dá)到閾值,將會(huì)調(diào)用System.gc()來做一次Full GC。這里說的堆外內(nèi)存主要說的是nio下的DirectByteBuffer,它會(huì)通過Unsafe接口通過os::malloc來分配內(nèi)存,然后將內(nèi)存的起始地址和大小存到DirectByteBuffer對(duì)象中,只有當(dāng)DirectByteBuffer被回收掉之后堆外內(nèi)存才可能被回收。具體堆外內(nèi)存回收的細(xì)節(jié)大家可以看下笨神的JVM源碼分析之堆外內(nèi)存完全解讀.
項(xiàng)目中顯示或隱式的調(diào)用了System.gc()。System.gc的詳情可見鏈接描述
老年代可用空間不夠了,導(dǎo)致它的原因有多種,但是常見的排查思路通過mat去分析堆內(nèi)存dump文件。
定位Full GC的原因gc日志永遠(yuǎn)都是我們排查gc問題最好的工具,所以強(qiáng)烈建議大家在線上配置-XX:+PrintGCDetails -Xloggc:/data/logs/gc.log方便我們?nèi)ザㄎ粏栴}。由于當(dāng)前項(xiàng)目沒有配置,只好用jstat -gccause去監(jiān)測(cè),博主監(jiān)測(cè)了五分鐘左右,得到如下信息:新生代、老年代、元空間內(nèi)存還很多,F(xiàn)GC漲了9次,并且對(duì)應(yīng)的LGCC都顯示為System.gc.由于虛擬機(jī)參數(shù)并沒有去配置-XX:MaxDirectMemorySize,所以其堆外內(nèi)存受限于當(dāng)前物理機(jī)內(nèi)存,故我們可以通過top去查看進(jìn)程占了多少內(nèi)存和通過free -m查看空閑內(nèi)存(當(dāng)然visualvm的插件和perftools都是查看堆外內(nèi)存使用情況很好的工具,不了解自行谷歌)。經(jīng)過內(nèi)存分析和業(yè)務(wù)分析之后,初步斷定不是堆外內(nèi)存導(dǎo)致的,而是由項(xiàng)目中有調(diào)用System.gc().
如何查找項(xiàng)目哪里有調(diào)用Full GC呢首先對(duì)項(xiàng)目全局進(jìn)行搜索System.gc(),如果沒有查到,那么就很可能是依賴的jar包里存在調(diào)用,如何在jar包中查找呢?在這里給大家推薦一款插件Btracegithub地址。BTrace是Java的安全可靠的動(dòng)態(tài)跟蹤工具。 他的工作原理是通過 instrument + asm 來對(duì)正在運(yùn)行的java程序中的class類進(jìn)行動(dòng)態(tài)增強(qiáng)。說他是安全可靠的,是因?yàn)樗鼘?duì)正在運(yùn)行的程序是只讀的。也就是說,他可以插入跟蹤語句來檢測(cè)和分析運(yùn)行中的程序,不允許對(duì)其進(jìn)行修改。因此他存在一些限制:
不能創(chuàng)建對(duì)象
不能創(chuàng)建數(shù)組
不能拋出和捕獲異常
不能調(diào)用任何對(duì)象方法和靜態(tài)方法
不能給目標(biāo)程序中的類靜態(tài)屬性和對(duì)象的屬性進(jìn)行賦值
不能有外部、內(nèi)部和嵌套類
不能有同步塊和同步方法
不能有循環(huán)(for, while, do..while)
不能繼承任何的類
不能實(shí)現(xiàn)接口
不能包含assert斷言語句
根據(jù)官方聲明,不恰當(dāng)?shù)氖褂肂trace會(huì)導(dǎo)致jvm崩潰,所以在上生產(chǎn)環(huán)境之前,一定要在本地充分驗(yàn)證腳本的正確性。Btrace的常見使用場(chǎng)景有:
分析哪些方法調(diào)用System.gc,獲取其調(diào)用棧
接口性能差,分析耗時(shí)情況
當(dāng)出現(xiàn)異常時(shí),分析方法的運(yùn)行時(shí)參數(shù)
線上有一個(gè)大對(duì)象ArrayList,查看其內(nèi)容
安裝使用BtraceBtrace依賴于JDK,首先要安裝好JDK并配置JDK的環(huán)境變量。
1.下載安裝包
</>復(fù)制代碼
下載地址:https://github.com/btraceio/btrace/releases/tag/v1.3.11
2.解壓縮
修改目錄權(quán)限:
3.配置環(huán)境變量
然后source更新環(huán)境變量
4.編寫btrace腳本
</>復(fù)制代碼
import static com.sun.btrace.BTraceUtils.jstack;
import static com.sun.btrace.BTraceUtils.println;
import static com.sun.btrace.BTraceUtils.str;
import static com.sun.btrace.BTraceUtils.strcat;
import static com.sun.btrace.BTraceUtils.timeMillis;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.TLS;
@BTrace
public class MyTest {
@OnMethod(clazz = "java.lang.System", method = "gc" )
public static void startMethod(){
println("****************************************");
jstack();
println("****************************************");
}
@OnMethod(clazz = "java.lang.System", method = "gc", location = @Location(Kind.RETURN))
public static void endMethod(){
println("=========================================");
jstack();
println("=========================================");
}
}
5.運(yùn)行btrace
通過jps -l獲得進(jìn)程的pid,然后通過 btrace
6.關(guān)閉btrace
經(jīng)過長(zhǎng)達(dá)一天的監(jiān)控,終于抓到了對(duì)應(yīng)的調(diào)用棧:
原因是項(xiàng)目中用到了jxl的Workbook來做Excel相關(guān)的功能,每次關(guān)閉Workbook的時(shí)候都會(huì)調(diào)用System.gc
至此,我們就已經(jīng)抓住了導(dǎo)致頻繁Full GC的鬼了,改動(dòng)方法也特別簡(jiǎn)單,在構(gòu)造WorkBook的時(shí)候,將其成員變量WorkbookSettings的成員變量gcDisabled設(shè)置為true即可避免此問題,或者添加vm參數(shù)-Djxl.nogc=true(不太推薦).
總結(jié)每次排查問題的時(shí)候遇到了很多困難,在總結(jié)的時(shí)候卻又不知道該說些什么~.~。特別感謝提供幫助的笨神、阿飛和零度。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/69357.html
摘要:是一款基于并發(fā)使用標(biāo)記清除算法的垃圾回收算法,只針對(duì)老年代進(jìn)行垃圾回收。收集器工作時(shí),工作線程和用戶線程可以并發(fā)執(zhí)行,以達(dá)到降低時(shí)間的目的。并發(fā)清理清理垃圾對(duì)象,這個(gè)階段線程和用戶線程并發(fā)執(zhí)行。 背景 我們上線Java服務(wù)的時(shí)候需要對(duì)其配置一些JVM參數(shù),如堆空間大小、虛擬機(jī)棧大小、垃圾回收算法。對(duì)于年輕代和老年代我們可以配置不同的垃圾回收算法。在一些對(duì)rt要求很高的場(chǎng)景,服務(wù)不能有長(zhǎng)...
摘要:一發(fā)生故障今天發(fā)現(xiàn)服務(wù)查詢一直卡住,就看了一下服務(wù)器當(dāng)時(shí)就愣住了就這一個(gè)服務(wù)就把占滿了,再看了下端口號(hào)出現(xiàn)了大量的。 一、發(fā)生故障 今天發(fā)現(xiàn)服務(wù)查詢一直卡住,就看了一下服務(wù)器: showImg(https://segmentfault.com/img/bVbrL5i?w=842&h=57); 當(dāng)時(shí)就愣住了就這一個(gè)服務(wù)就把CPU占滿了,再看了下端口號(hào): showImg(https://s...
摘要:結(jié)構(gòu)型模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。行為型模式模版方法模式命令模式迭代器模式觀察者模式中介者模式備忘錄模式解釋器模式模式狀態(tài)模式策略模式職責(zé)鏈模式責(zé)任鏈模式訪問者模式。 主要版本 更新時(shí)間 備注 v1.0 2015-08-01 首次發(fā)布 v1.1 2018-03-12 增加新技術(shù)知識(shí)、完善知識(shí)體系 v2.0 2019-02-19 結(jié)構(gòu)...
摘要:直接顯示了一個(gè)疑似內(nèi)存泄漏的問題。然后分析文件給出的信息,發(fā)現(xiàn)一個(gè)叫的類。文件里面說的內(nèi)存泄漏的大概的意思就是說,這個(gè)類里面的存放的東西太多了,爆掉了。修改了代碼將調(diào)用的地方改成了單例。修改完線上跑了一段日子,后來也沒有出現(xiàn)過這樣的問題。 問題描述: ????早上去公司上班,突然就郵件一直報(bào)警,接口報(bào)異常,然后去查服務(wù)器的運(yùn)行情況,發(fā)現(xiàn)java的cpu爆了.接著就開始排查問題 問題解決...
閱讀 1540·2023-04-26 02:50
閱讀 3549·2023-04-26 00:28
閱讀 1937·2023-04-25 15:18
閱讀 3219·2021-11-24 10:31
閱讀 991·2019-08-30 13:00
閱讀 1005·2019-08-29 15:19
閱讀 1774·2019-08-29 13:09
閱讀 2983·2019-08-29 13:06
极致性价比!云服务器续费无忧!
Tesla A100/A800、Tesla V100S等多种GPU云主机特惠2折起,不限台数,续费同价。
NVIDIA RTX 40系,高性价比推理显卡,满足AI应用场景需要。
乌兰察布+上海青浦,满足东推西训AI场景需要