Java常用命令及性能調(diào)優(yōu)工具

聲明:原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明出處。http://www.lxweimin.com/u/e02df63eaa87

1、Linux命令

1.1 top命令

top命令

top命令的輸出可以分為上下兩部分:系統(tǒng)統(tǒng)計(jì)信息和進(jìn)程統(tǒng)計(jì)信息。

系統(tǒng)統(tǒng)計(jì)信息:

  • 第一行:任務(wù)隊(duì)列信息。等同于uptime命令
20:30:40 up 71 days, 21:36,  1 user,  load average: 0.15, 0.16, 0.13

系統(tǒng)當(dāng)前時(shí)間、系統(tǒng)運(yùn)行時(shí)間、當(dāng)前登錄用戶數(shù)。load average表示系統(tǒng)的平均負(fù)載(1分鐘內(nèi)、5分鐘內(nèi)、15分鐘內(nèi))。

  • 第二行:進(jìn)程統(tǒng)計(jì)信息。分別為總的進(jìn)程數(shù)、運(yùn)行中的進(jìn)程數(shù)、睡眠進(jìn)程數(shù)、停止的進(jìn)程數(shù)以及僵尸進(jìn)程數(shù)。
Tasks:  75 total,   1 running,  74 sleeping,   0 stopped,   0 zombie
  • 第三行:CPU統(tǒng)計(jì)信息。
Cpu(s):  0.4%us,  0.2%sy,  0.0%ni, 99.4%id,  0.1%wa,  0.0%hi,  0.0%si,  0.0%st

us:用戶態(tài)CPU占用率、sy:內(nèi)核態(tài)CPU占用率、ni:用戶進(jìn)程空間改變過(guò)優(yōu)先級(jí)的進(jìn)程CPU占用率、id:空閑CPU占用率、wa:等待輸入輸出的CPU時(shí)間百分比、hi:硬件中斷請(qǐng)求、si:軟件中斷請(qǐng)求、st:CPU服務(wù)于軟中斷所耗費(fèi)的時(shí)間總額。

  • 第四行:內(nèi)存統(tǒng)計(jì)信息。
Mem:   1922244k total,  1200496k used,   721748k free,   181508k buffers

依次表示物理內(nèi)存總量、已使用內(nèi)存量、空閑內(nèi)存量、內(nèi)核緩沖使用量。

  • 第五行:交換區(qū)統(tǒng)計(jì)信息。
Swap:        0k total,        0k used,        0k free,   435204k cached

依次表示交換區(qū)總量、已使用交互區(qū)總量、空閑交換區(qū)總量、緩沖的交換區(qū)總量。

進(jìn)程統(tǒng)計(jì)信息:

  • PID:進(jìn)程id
  • USER:進(jìn)程所有者的用戶id
  • PR:優(yōu)先級(jí)
  • NI:nice值。負(fù)值表示高優(yōu)先級(jí)、正值表示低優(yōu)先級(jí)
  • VIRT:進(jìn)程使用的虛擬內(nèi)存總量。VIRT=SWAP+RES
  • RES:進(jìn)程使用的、未被換出的物理內(nèi)存大小
  • SHR:共享內(nèi)存大小(KB)
  • S:進(jìn)程狀態(tài)。R-運(yùn)行、S-睡眠、D-不可中斷的睡眠、T-跟蹤/停止、Z-僵尸
  • %CPU:上次更新到現(xiàn)在的CPU時(shí)間占用百分比
  • %MEM:進(jìn)程使用的物理內(nèi)存百分比
  • %TIME+:進(jìn)程使用的CPU時(shí)間總計(jì)
  • COMMAND:命令名

top常用子命令:

  • h:幫助
  • k:終止一個(gè)進(jìn)程
  • c:切換顯示完整的命令行
  • M:按照內(nèi)存大小排序
  • P:按照CPU占用百分比排序
1.2 sar命令

sar命令也是Linux系統(tǒng)中重要的性能檢測(cè)工具之一,可周期性的對(duì)內(nèi)存和CPU的使用情況進(jìn)行采樣。如下:

sar 1 5

表示每隔1秒采樣1次,共采樣5次。

Linux 2.6.32-573.22.1.el6.x86_64 (-)    03/14/2017  _x86_64_    (1 CPU)

02:40:35 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
02:40:36 PM     all      0.99      0.00      0.99      0.00      0.00     98.02
02:40:37 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
02:40:38 PM     all      1.00      0.00      0.00      0.00      0.00     99.00
02:40:39 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
02:40:40 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
Average:        all      0.40      0.00      0.20      0.00      0.00     99.40

option選項(xiàng):

  • -A:所有報(bào)告。
  • -u:CPU利用率。默認(rèn)選項(xiàng)。
  • -d:磁盤使用情況。
  • -b:I/O使用情況。
  • -q:查看隊(duì)列長(zhǎng)度。
  • -r:內(nèi)存使用情況。
  • -n:查看網(wǎng)絡(luò)信息統(tǒng)計(jì)。【ALL】
  • -o:將采樣結(jié)果輸出到文件
1.3 vmstat命令

vmstat命令同樣也是Linux系統(tǒng)中重要的性能檢測(cè)工具之一,不僅可周期性的對(duì)內(nèi)存、CPU進(jìn)行采樣,還可以對(duì)swap使用進(jìn)行采樣。

vmstat 1 5

表示每隔1秒采樣一次,共采樣5次。

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 401032 183320 732700    0    0     3     2    3    6  0  0 99  0  0    
 0  0      0 401016 183320 732700    0    0     0     0  234  512  0  1 99  0  0    
 0  0      0 401016 183320 732700    0    0     0     0  220  495  0  0 100  0  0   
 0  0      0 401016 183320 732700    0    0     0    32  240  518  1  0 99  0  0    
 0  0      0 401016 183320 732700    0    0     0     0  244  511  0  0 100  0  0
  • procs
  • r:等待運(yùn)行的進(jìn)程數(shù)
  • b:處在非中斷睡眠狀態(tài)的進(jìn)程數(shù)
  • memory
  • swpd:虛擬內(nèi)存使用情況(KB)
  • free:空閑內(nèi)存大小(KB)
  • buff:表示塊設(shè)備(block device)所占用的緩存頁(yè),包括:直接讀寫塊設(shè)備、以及文件系統(tǒng)元數(shù)據(jù)(metadata),比如SuperBlock所使用的緩存頁(yè)(KB)
  • cache:表示普通文件數(shù)據(jù)所占用的緩存頁(yè)
  • swap
  • si:從磁盤交換到內(nèi)存的交換頁(yè)數(shù)量(KB/秒)
  • so:從內(nèi)存交換到磁盤的交換頁(yè)數(shù)量(KB/秒)
  • io
  • bi:發(fā)送到塊設(shè)備的塊數(shù)(塊/秒)
  • bo:從塊設(shè)備接收到的塊數(shù)(塊/秒)
  • system
  • in:每秒中斷數(shù)
  • cs:每秒上下文切換次數(shù)
  • cpu
  • us:用戶態(tài)CPU占用率
  • sy:內(nèi)核態(tài)CPU占用率
  • id:空閑CPU占用率
    -wa:等待輸入輸出的CPU時(shí)間百分比
  • st:CPU服務(wù)于軟中斷所耗費(fèi)的時(shí)間總額
1.4 iostat命令

iostat可以提供詳盡的I/O信息。

iostat 1 2

表示每隔1秒采樣1次,共采樣2次。

Linux 2.6.32-573.22.1.el6.x86_64 (-)    03/14/2017  _x86_64_    (1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.42    0.00    0.17    0.05    0.00   99.36

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
vda               0.49         5.86         4.35   39755548   29531688
vdb               0.00         0.00         0.00       1392          0

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.00    0.00    0.00    0.00    0.00   99.00

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
vda               0.00         0.00         0.00          0          0
vdb               0.00         0.00         0.00          0          0
  • tps:該設(shè)備每秒的傳輸次數(shù)
  • Blk_read/s:每秒從設(shè)備讀取的數(shù)據(jù)量
  • Blk_wrtn/s:每秒向設(shè)備寫入的數(shù)據(jù)量
  • Blk_read:讀取的總數(shù)據(jù)量
  • Blk_wrtn:寫入的總數(shù)據(jù)量
1.5 pidstat命令

pidstat也是一個(gè)功能強(qiáng)大的性能檢測(cè)工具。不僅可以檢測(cè)進(jìn)程的性能,還可以檢測(cè)線程的性能。

1.5.1 CPU使用率監(jiān)控

下面的程序中,開啟了3個(gè)線程,其中一個(gè)大量占用CPU,其他2個(gè)線程處于空閑狀態(tài)。

public class CPUMain {
    public static class BusyCPUTask implements Runnable {
        @Override
        public void run() {
            while (true) {
                double i = Math.random() * Math.random();
            }
        }
    }
    public static class LazyCPUTask implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    TimeUnit.SECONDS.sleep(1);
                }
            } catch (Exception e) {
                // do nothing
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new BusyCPUTask()).start();
        new Thread(new LazyCPUTask()).start();
        new Thread(new LazyCPUTask()).start();
    }
}
  • 1、使用jps -l找到該Java程序的PID:
[root@- ~]# jps -l
19077 sun.tools.jps.Jps
19064 command.CPUMain
17338 org.elasticsearch.bootstrap.Elasticsearch
17851 org.jruby.Main
  • 2、使用pidstat命令輸出該程序的CPU使用情況:
[root@- ~]# pidstat -p 19064 -u 1 3
Linux 2.6.32-573.22.1.el6.x86_64 (-)    03/14/2017  _x86_64_    (1 CPU)
05:49:01 PM       PID    %usr %system  %guest    %CPU   CPU  Command
05:49:02 PM     19064   99.00    0.00    0.00   99.00     0  java
05:49:03 PM     19064  100.00    0.00    0.00  100.00     0  java
05:49:04 PM     19064   99.00    0.00    0.00   99.00     0  java
Average:        19064   99.33    0.00    0.00   99.33     -  java

-p 指定進(jìn)程的ID,-u 對(duì)CPU使用率進(jìn)行監(jiān)控;每隔1秒采樣1次,共采樣3次。

  • 3、使用-t參數(shù)找出最占CPU的線程
[root@- ~]# pidstat -p 19064  -u -t 1 1
Linux 2.6.32-573.22.1.el6.x86_64 (-)    03/14/2017  _x86_64_    (1 CPU)
05:56:00 PM      TGID       TID    %usr %system  %guest    %CPU   CPU  Command
05:56:01 PM     19064         -   99.00    0.00    0.00   99.00     0  java
05:56:01 PM         -     19064    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19065    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19066    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19067    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19068    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19069    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19070    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19071    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19072    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19073    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19074  100.00    0.00    0.00  100.00     0  |__java
05:56:01 PM         -     19075    0.00    0.00    0.00    0.00     0  |__java
05:56:01 PM         -     19076    0.00    0.00    0.00    0.00     0  |__java
... ...

可以看到, 19074 這個(gè)線程占用了大量CPU。
備注:上述2和3兩個(gè)過(guò)程可以使用top -p 19064 -H命令查出哪個(gè)線程占用大量CPU,如下:

[root@- ~]# top -p 19064 -H
top - 17:57:41 up 78 days, 19:03,  3 users,  load average: 1.00, 0.86, 0.55
Tasks:  13 total,   1 running,  12 sleeping,   0 stopped,   0 zombie
Cpu(s): 99.7%us,  0.3%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1922244k total,  1584308k used,   337936k free,   185344k buffers
Swap:        0k total,        0k used,        0k free,   776028k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                        
19064 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19065 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.07 java                                                                                                                            
19066 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19067 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19068 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19069 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19070 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19071 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19072 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java                                                                                                                            
19073 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.12 java                                                                                                                            
19074 root      20   0 2414m  23m  11m R 99.6  1.3   9:09.31 java                                                                                                                            
19075 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.01 java                                                                                                                            
19076 root      20   0 2414m  23m  11m S  0.0  1.3   0:00.00 java

得到的結(jié)果同樣是**19074 **這個(gè)線程。

  • 4、jstack定位線程棧
    jstack 19064 > jstack.log
  • 5、查看19074線程情況
    通過(guò)使用命令printf %x 19074得到19074的16進(jìn)制:4a82
    查看4a82線程:
"Thread-0" #8 prio=5 os_prio=0 tid=0x00007fae380fa800 nid=0x4a82 runnable [0x00007fae3c551000]
   java.lang.Thread.State: RUNNABLE
        at command.CPUMain$BusyCPUTask.run(CPUMain.java:14)
        at java.lang.Thread.run(Thread.java:745)

結(jié)論:可以定位到線程在執(zhí)行CPUMain.java:14占用了大量CPU。

1.5.2 I/O監(jiān)控

下面的程序中,開啟了3個(gè)線程,其中一個(gè)大量占用I/O,其他2個(gè)線程處于空閑狀態(tài)。

public class IOMain {
    public static class BusyIOTask implements Runnable {
        @Override
        public void run() {
            try {
                FileOutputStream fos;
                FileInputStream fis;
                while (true) {
                    fos = new FileOutputStream(new File("temp"));
                    for (int i = 0; i < 1000; i++) {
                        fos.write(i);           // 寫操作
                    }
                    fos.close();
                    fis = new FileInputStream(new File("temp"));
                    while (fis.read() != -1);   // 讀操作
                    fis.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static class LazyIOTask implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    TimeUnit.SECONDS.sleep(1);
                }
            } catch (Exception e) {
                // do nothing
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new IOMain.BusyIOTask()).start();
        new Thread(new IOMain.LazyIOTask()).start();
        new Thread(new IOMain.LazyIOTask()).start();
    }
}
  • 1、使用jps -l找到該Java程序的PID:
[root@- ~]# jps -l
17338 org.elasticsearch.bootstrap.Elasticsearch
17851 org.jruby.Main
19323 sun.tools.jps.Jps
19310 command.IOMain
  • 2、使用pidstat命令輸出該程序的各個(gè)線程的I/O使用情況:
[root@- ~]# pidstat -p 19310 -d -t 1 3
Linux 2.6.32-573.22.1.el6.x86_64 (-)    03/14/2017  _x86_64_    (1 CPU)
06:30:13 PM      TGID       TID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
06:30:14 PM     19310         -      0.00   3482.83   1741.41  java
06:30:14 PM         -     19310      0.00      0.00      0.00  |__java
06:30:14 PM         -     19311      0.00      0.00      0.00  |__java
06:30:14 PM         -     19312      0.00      0.00      0.00  |__java
06:30:14 PM         -     19313      0.00      0.00      0.00  |__java
06:30:14 PM         -     19314      0.00      0.00      0.00  |__java
06:30:14 PM         -     19315      0.00      0.00      0.00  |__java
06:30:14 PM         -     19316      0.00      0.00      0.00  |__java
06:30:14 PM         -     19317      0.00      0.00      0.00  |__java
06:30:14 PM         -     19318      0.00      0.00      0.00  |__java
06:30:14 PM         -     19319      0.00      0.00      0.00  |__java
06:30:14 PM         -     19320      0.00   3478.79   1741.41  |__java
06:30:14 PM         -     19321      0.00      0.00      0.00  |__java
06:30:14 PM         -     19322      0.00      0.00      0.00  |__java
... ...
  • 3、定位線程棧
    同樣地使用jstack命令,導(dǎo)出該程序的線程棧,查找nid=19320(0x4b78)的線程,即可定位問(wèn)題。
1.5.3 內(nèi)存監(jiān)控

使用pidstat命令,還可以監(jiān)視指定進(jìn)程的內(nèi)存的使用情況。

[root@- test]# pidstat -p 17338 -r 1 3
Linux 2.6.32-573.22.1.el6.x86_64 (-)    03/14/2017  _x86_64_    (1 CPU)

06:36:36 PM       PID  minflt/s  majflt/s     VSZ    RSS   %MEM  Command
06:36:37 PM     17338      0.00      0.00 2677708 280504  14.59  java
06:36:38 PM     17338      0.00      0.00 2677708 280504  14.59  java
06:36:39 PM     17338      0.00      0.00 2677708 280504  14.59  java
Average:        17338      0.00      0.00 2677708 280504  14.59  java
  • minflt/s:該進(jìn)程每秒minor faults(不需要從磁盤中調(diào)出內(nèi)存頁(yè))的總數(shù)
  • majflt/s:該進(jìn)程每秒major faults(需要從磁盤中調(diào)出內(nèi)存頁(yè))的總數(shù)
  • VSZ:該進(jìn)程使用的虛擬內(nèi)存大小(KB)
  • RSS:該進(jìn)程使用的物理內(nèi)存大小(KB)
  • %MEM:內(nèi)存占用率

2、JDK命令

2.1 jps命令

jps命令類似于Linux的ps,只不過(guò)ps是查看Linux系統(tǒng)的進(jìn)程,jps只是列出當(dāng)前用戶啟動(dòng)的Java進(jìn)程

  • jps
[root@- ~]# jps
17338 Elasticsearch
17851 Main
21166 Jps
  • jps -q:只輸出進(jìn)程id
  • jps -m:輸出傳遞給Java Main函數(shù)的參數(shù)
  • jps -l:輸出Main函數(shù)的完整路徑
  • jps -v:輸出傳遞給JVM的參數(shù)
2.2 jstat命令

jstat命令用于觀察Java程序的運(yùn)行時(shí)工具。

Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

option可選項(xiàng):

  • -class:顯示ClassLoader的相關(guān)信息
[root@- ~]# jstat -class -t 17338
Timestamp       Loaded  Bytes  Unloaded  Bytes     Time   
      4302040.9   8482 15664.4       12    12.0       7.94

Loaded表示載入類的數(shù)量、Bytes表示載入類的大小、Unloaded表示卸載類的數(shù)量、Bytes表示卸載類的大小、Time表示在加載及卸載類上所花的時(shí)間。

  • -compiler:顯示JIT編譯的相關(guān)信息
[root@- ~]# jstat -compiler -t 17338
Timestamp       Compiled Failed Invalid   Time   FailedType FailedMethod
      4312097.9    12812      0       0    73.32          0

Complied表示編譯任務(wù)執(zhí)行的次數(shù)、Failed表示編譯失敗的次數(shù)、Invalid表示不可用的次數(shù)、Time表示編譯的總耗時(shí)、FailedType表示最后一次編譯失敗的類型、FailedMethod表示最后一次編譯失敗的類名和方法名。

  • -gc:顯示與GC相關(guān)的堆信息
[root@- ~]# jstat -gc -t 17338
Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
      4312491.0 8512.0 8512.0  76.1   0.0   68160.0  15675.5   439104.0   18409.8   47780.0 47055.7 5600.0 5363.6    644    4.077   4      0.176    4.253
  • S0C:S0(From)的大小(KB)

  • S1C:S1(To)的大小(KB)

  • S0U:S0(From)已使用的大小(KB)

  • S1U:S1(To)已使用的大小(KB)

  • EC:Eden區(qū)的大小(KB)

  • EU:Eden已使用的大小(KB)

  • OC:老年代大小(KB)

  • OU:老年代已使用的大小(KB)

  • MC:方法區(qū)大小(KB)

  • MU:方法區(qū)已使用大小(KB)

  • CCSC:壓縮類空間大小(KB)

  • CCSU:壓縮類空間已使用大小(KB)

  • PC:永久區(qū)大小(KB)

  • PU:永久區(qū)已使用大小(KB)

  • YGC:新生代GC次數(shù)

  • YGCT:新生代GC耗時(shí)

  • FGC:Full GC次數(shù)

  • FGCT:Full GC耗時(shí)

  • GCT:GC總耗時(shí)

  • -gccapacity:顯示各個(gè)代的容量及使用情況

[root@- ~]# jstat -gccapacity -t 17338
Timestamp        NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
      4313185.9  85184.0  85184.0  85184.0 8512.0 8512.0  68160.0   439104.0   439104.0   439104.0   439104.0      0.0 1091584.0  47780.0      0.0 1048576.0   5600.0    644     4

-gc相比,不僅輸出了各個(gè)代當(dāng)前的大小,還輸出了各個(gè)代的最小、最大值。

  • NGCMN:新生代最小值(KB)

  • NGCMX:新生代最大值(KB)

  • NGC:當(dāng)前新生代大小(KB)

  • OGCMN:老年代最小值(KB)

  • OGCMX:老年代最大值(KB)

  • PGCMN:永久區(qū)最小值(KB)

  • PGCMX:永久區(qū)最大值(KB)

  • -gccause:顯示垃圾收集相關(guān)信息(同gcutil),同時(shí)顯示最后一次或當(dāng)前正在發(fā)生的垃圾收集的誘發(fā)原因

[root@- ~]# jstat -gccause -t 17338
Timestamp         S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 
      4313692.2   0.89   0.00  43.07   4.19  98.48  95.78    644    4.077     4    0.176    4.253 Allocation Failure   No GC
  • LGCC:最近一次GC的的原因

  • GCC:當(dāng)前GC的原因

  • -gcnew:顯示新生代信息

[root@- ~]# jstat -gcnew -t 17338
Timestamp        S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
      4314215.7 8512.0 8512.0   76.1    0.0  6   6 4256.0  68160.0  33355.0    644    4.077
  • TT:新生代對(duì)象晉升到老年代對(duì)象的年齡

  • MTT:新生代對(duì)象晉升到老年代對(duì)象的年齡最大值

  • DSS:所需的幸存區(qū)大小

  • -gcnewcapacity:顯示新生代容量及使用情況

[root@- ~]# jstat -gcnewcapacity -t 17338
Timestamp         NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
      4314357.1    85184.0    85184.0    85184.0   8512.0   8512.0   8512.0   8512.0    68160.0    68160.0   644     4
  • S0CMX:S0區(qū)的最大值

  • S1CMX:S1區(qū)的最大值

  • ECMX:Eden區(qū)的最大值

  • -gcold:顯示老年代和永久代的信息

[root@- ~]# jstat -gcold -t 17338
Timestamp          MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
      4314463.2  47780.0  47055.7   5600.0   5363.6    439104.0     18409.8    644     4    0.176    4.253
  • -gcoldcapacity:顯示老年代容量
[root@- ~]# jstat -gcoldcapacity -t 17338
Timestamp          OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT   
      4314490.9    439104.0    439104.0    439104.0    439104.0   644     4    0.176    4.253
  • -gcutil:顯示垃圾收集信息
[root@- ~]# jstat -gcutil -t 17338
Timestamp         S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
      4314594.9   0.89   0.00  52.34   4.19  98.48  95.78    644    4.077     4    0.176    4.253
  • -printcompilation:輸出HotSpot編譯方法的統(tǒng)計(jì)
[root@- ~]# jstat -printcompilation -t 17338
Timestamp       Compiled  Size  Type Method
      4314622.9    12827    173    1 org/elasticsearch/cluster/routing/allocation/decider/AllocationDeciders canRebalance

其他選項(xiàng):

  • -t:在輸出信息前加入一個(gè)時(shí)間戳,顯示程序的運(yùn)行時(shí)間
  • -h:在周期性數(shù)據(jù)輸出時(shí),輸出多少行數(shù)據(jù)后,跟著輸出一個(gè)表頭信息
  • interval:指定輸出統(tǒng)計(jì)數(shù)據(jù)的周期(毫秒)
  • count:指定一共輸出多少次數(shù)據(jù)
2.3 jinfo命令

jinfo可以查看正在運(yùn)行的Java程序的JVM參數(shù),并且支持運(yùn)行時(shí)修改個(gè)別參數(shù)。

jinfo [option] <pid>

option可選項(xiàng):

  • -flag <name> to print the value of the named VM flag,打印指定JVM的參數(shù)值
  • -flag [+|-]<name> to enable or disable the named VM flag,設(shè)置指定JVM參數(shù)的boolean值
  • -flag <name>=<value> to set the named VM flag to the given value,設(shè)置指定JVM參數(shù)值
  • -flags to print VM flags,打印JVM的參數(shù)值
  • -sysprops to print Java system properties,打印Java系統(tǒng)的屬性信息
  • <no option> to print both of the above,打印flags和syspros
2.4 jmap命令

jmap命令能生成Java應(yīng)用程序的堆快照和對(duì)象的統(tǒng)計(jì)信息。

jmap -histo 17338 > jmap.log
 num     #instances         #bytes  class name
----------------------------------------------
   1:        119627       16888576  [C
   2:         74845        8336640  [B
   3:         14991        3763272  [I
   4:         66990        3215520  java.lang.management.MemoryUsage
   5:         32973        2374056  java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
   6:         42965        2055352  [Ljava.lang.Object;
   7:         81756        1962144  java.lang.String
   8:          9035         994824  java.lang.Class
   9:          6709         858752  sun.nio.fs.UnixFileAttributes
  10:         24718         790976  sun.nio.fs.UnixPath
  ... ...
3729:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total       1077805       61629024

上述命令輸出了內(nèi)存中實(shí)例的數(shù)量和大小。

生成堆快照信息:

jmap -dump:format=b,file=heap.hprof 17338
2.5 jhat命令

jhat命令可以分析Java程序的堆快照。

[root@- ~]# jhat heap.hprof 
Reading from heap.hprof...
Dump file created Wed Mar 15 15:42:02 CST 2017
Snapshot read, resolving...
Resolving 1183100 objects...
Chasing references, expect 236 dots............................................................................................................................................................................................................................................
Eliminating duplicate references............................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

可以通過(guò)瀏覽器訪問(wèn)7000端口查看堆快照信息。

2.6 jstack命令

用于輸出Java應(yīng)用程序的線程棧信息。

public class DeadLockMain {
    private static String A = "A";
    private static String B = "B";

    public void deadLock() {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (A) {
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    synchronized (B) {
                        System.out.println("thread1");
                    }
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (B) {
                    synchronized (A) {
                        System.out.println("thead2");
                    }
                }
            }
        });
        t1.start();
        t2.start();
    }

    public static void main(String[] args) {
        new DeadLockMain().deadLock();
    }
}

上述代碼是一個(gè)簡(jiǎn)單的會(huì)發(fā)生死鎖的例子,兩個(gè)線程分別持有A和B,并分別請(qǐng)求B和A,導(dǎo)致死鎖產(chǎn)生。
使用jstack打印上述進(jìn)程的線程棧信息,部分輸出如下:

"Thread-1" #9 prio=5 os_prio=0 tid=0x00007f0ff410b000 nid=0x56d9 waiting for monitor entry [0x00007f0fe4bfa000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at command.DeadLockMain$2.run(DeadLockMain.java:33)
    - waiting to lock <0x00000000e2a77cc0> (a java.lang.String)
    - locked <0x00000000e2a77cf0> (a java.lang.String)
    at java.lang.Thread.run(Thread.java:745)

"Thread-0" #8 prio=5 os_prio=0 tid=0x00007f0ff40fb000 nid=0x56d8 waiting for monitor entry [0x00007f0fe4cfb000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at command.DeadLockMain$1.run(DeadLockMain.java:23)
    - waiting to lock <0x00000000e2a77cf0> (a java.lang.String)
    - locked <0x00000000e2a77cc0> (a java.lang.String)
    at java.lang.Thread.run(Thread.java:745)




Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f0fd8004e28 (object 0x00000000e2a77cc0, a java.lang.String),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007f0fd80062c8 (object 0x00000000e2a77cf0, a java.lang.String),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
    at command.DeadLockMain$2.run(DeadLockMain.java:33)
    - waiting to lock <0x00000000e2a77cc0> (a java.lang.String)
    - locked <0x00000000e2a77cf0> (a java.lang.String)
    at java.lang.Thread.run(Thread.java:745)
"Thread-0":
    at command.DeadLockMain$1.run(DeadLockMain.java:23)
    - waiting to lock <0x00000000e2a77cf0> (a java.lang.String)
    - locked <0x00000000e2a77cc0> (a java.lang.String)
    at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

從上述輸出來(lái)看,很容易找到死鎖,并且可以看到發(fā)生死鎖的兩個(gè)線程以及兩個(gè)線程的持有和等待的對(duì)象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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