應用上線之后總會出現(xiàn)各種各樣的問題,這些問題包括但不限于一下幾類問題:
- 線程問題
- cpu消耗較多
- 內(nèi)存問題
- 進程莫名crash或者被系統(tǒng)kill
- gc時間過長
在排查這類問題時,jdk提供了一系列工具幫助開發(fā)人員更好地定位問題。
jstack
jstack主要用來排查線程相關(guān)的問題,比如應用內(nèi)線程數(shù)飚高,線程死鎖,以及應用cpu過高,在遇到此類問題時可以通過jstack打印出線程棧信息。首先通過ps命令或者jps找出應用的進程id,然后通過jstack將棧信息打印到文件中;
jstack的用法如下:

通過jstack可以知道應用內(nèi)的線程數(shù)正在做什么,常用的用法是通過jstack -l <pid> > stack_<pid>.log,將線程棧信息打印到文件中,查看線程的執(zhí)行情況,若遇到應用進程占用cpu較多,可以通過top -p pid-H獲取到是哪個線程消耗cpu較多,然后將線程id轉(zhuǎn)換成十六進制,從線程棧文件找出對應的線程正在做什么,排查死鎖問題,則直接查找線程棧文件,基本可以找出來大部分的死鎖的問題。
jmap
排查內(nèi)存溢出非常好用的工具,通過jmap可以打印出jvm堆中對象的數(shù)量及引用關(guān)系,在dump堆之后可以通過MAT或者HA分析出哪個對象實例占用較多,是否有內(nèi)存泄露的情況。
jmap的用法如下:

常用的用法有:
jmap -histo:live <pid>,這種用法會強制執(zhí)行一次fgc;
jmap -heap <pid>,直接打印出各對象實例的分布情況;
jmap -dump:[live],format=b,file=dump.bin <pid>,將heap dump到指定文件中
jstat
jstat在排查gc問題時真的很好用,它能夠提供一些統(tǒng)計信息,包括gc次數(shù),gc原因,內(nèi)存占用等。還是先來看一下jstat的用法吧:

比較常用的用法有:
jstat -gcutil <pid> [interval],每隔interval(ms)打印出進程pid的gc情況;
jstat -gccause <pid> [interval],對于gcutil選項,該選項會將gc的原因列出來;
jinfo
jinfo主要用來查詢jvm進程的運行時的jvm參數(shù),以及修改jvm運行時的參數(shù),主要用法如下:
jinfo -flag <name> <pid>,查詢進程pid name的參數(shù)值;
jinfo -flag <name>=<value> <pid>,設置jvm參數(shù)name的值為value;
jinfo -flag [+|-]<name>,啟用某個參數(shù)或禁用某個參數(shù)。
另外通過btrace、HSDB這些工具可以查看到應用中更為細節(jié)的東西,在排查問題的時候真的好用,誰用誰知道。
工具雖然好用,但是也只能事后幫助我們排查具體問題,在平時的編碼過程過還是需要我們養(yǎng)成良好的編碼習慣,遵循最佳實踐,合理配置jvm參數(shù),才能減少此類問題的發(fā)生。