天天看點

線上問題排查常用指令

作者:迷茫的田略略略

線上問題排查常用指令

記憶體瓶頸

free

free 是檢視記憶體使用情況,包括實體記憶體、交換記憶體 (swap) 和核心緩沖區記憶體。

free -h -s 3 表示每隔三秒輸出一次記憶體情況,指令如下

[1014154@cc69dd4c5-4tdb5 ~]$ free
              total        used        free      shared  buff/cache   available
Mem:      119623656    43052220    45611364     4313760    30960072    70574408
Swap:             0           0           0
[1014154@cc69dd4c5-4tdb5 ~]$ free -h -s 3
              total        used        free      shared  buff/cache   available
Mem:           114G         41G         43G        4.1G         29G         67G
Swap:            0B          0B          0B

              total        used        free      shared  buff/cache   available
Mem:           114G         41G         43G        4.1G         29G         67G
Swap:            0B          0B          0B
           
  • Mem :是記憶體的使用情況。
  • Swap :是交換空間的使用情況。
  • total :系統總的可用實體記憶體和交換空間大小。
  • used :已經被使用的實體記憶體和交換空間。
  • free :還有多少實體記憶體和交換空間可用使用,是真正尚未被使用的實體記憶體數量。
  • shared :被共享使用的實體記憶體大小。
  • buff/cache :被 buffer(緩沖區) 和 cache(緩存) 使用的實體記憶體大小。
  • available :還可以被應用程式使用的實體記憶體大小,它是從應用程式的角度看到的可用記憶體數量,available ≈ free + buffer + cache。

交換空間 (swap space)

swap space 是磁盤上的一塊區域,當系統實體記憶體吃緊時,Linux 會将記憶體中不常通路的資料儲存到 swap 上,這樣系統就有更多的實體記憶體為各個程序服務,而當系統需要通路 swap 上存儲的内容時,再将 swap 上的資料加載到記憶體中,這就是常說的換出和換入。交換空間可以在一定程度上緩解記憶體不足的情況,但是它需要讀寫磁盤資料,是以性能不是很高。

vmstat(推薦)

vmstat(VirtualMeomoryStatistics,虛拟記憶體統計)是 Linux 中監控記憶體的常用工具,可對作業系統的虛拟記憶體、程序、CPU 等的整體情況進行監視,推薦使用。

vmstat 5 3 表示每隔 5 秒統計一次,一共統計三次。

[1014154@cc69dd4c5-4tdb5 ~]$ vmstat 5 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 8  0      0 45453212 374768 30763728    0    0    14    99    1    1 11 10 78  0  1
10  0      0 45489232 374768 30763360    0    0     2  1275 95118 97908 13 11 75  0  1
 6  0      0 45452908 374768 30765148    0    0     0  3996 89924 92073 12 10 78  0  1
           

procs

r:表示運作和等待 CPU 時間片的程序數(就是說多少個程序真的配置設定到 CPU),這個值如果長期大于系統 CPU 個數,說明 CPU 不足,需要增加 CPU。b:表示在等待資源的程序數,比如正在等待 I/O 或者記憶體交換等。

memory

swpd:表示切換到記憶體交換區的記憶體大小,即虛拟記憶體已使用的大小(機關 KB),如果大于 0,表示你的機器實體記憶體不足了,如果不是程式記憶體洩露的原因,那麼你該更新記憶體了或者把耗記憶體的任務遷移到其他機器。free:表示目前空閑的實體記憶體。buff:表示緩沖大小,一般對塊裝置的讀寫才需要緩沖 Cache:表示緩存大小,一般作為檔案系統進行緩沖,頻繁通路的檔案都會被緩存,如果 cache 值非常大說明緩存檔案比較多,如果此時 io 中的 bi 比較小,說明檔案系統效率比較好。

swap

si:表示資料由磁盤讀入記憶體;通俗的講就是每秒從磁盤讀入虛拟記憶體的大小,如果這個值大于 0,表示實體記憶體不夠用或者記憶體洩露了,要查找耗記憶體程序解決掉。so:表示由記憶體寫入磁盤,也就是由記憶體交換區進入記憶體的資料大小。

注意:一般情況下 si、so 的值都為 0,如果 si、so 的值長期不為 0,則說明系統記憶體不足,需要增加系統記憶體

io

bi:表示由塊裝置讀入資料的總量,即讀磁盤,機關 kb/s bo:表示寫到塊裝置資料的總量,即寫磁盤,機關 kb/s

注意:如果 bi+bo 的值過大,且 wa 值較大,則表示系統磁盤 IO 瓶頸。

system

in:表示某一時間間隔内觀測到的每秒裝置終端數。cs:表示每秒産生的上下文切換次數,這個值要越小越好,太大了,要考慮調低線程或者程序的數目。例如在 apache 和 nginx 這種 web 伺服器中,我們一般做性能測試時會進行幾千并發甚至幾萬并發的測試,選擇 web 伺服器的程序可以由程序或者線程的峰值一直下調,壓測,直到 cs 到一個比較小的值,這個程序和線程數就是比較合适的值了。系統調用也是,每次調用系統函數,我們的代碼就會進入核心空間,導緻上下文切換,這個是很耗資源,也要盡量避免頻繁調用系統函數。上下文切換次數過多表示你的 CPU 大部分浪費在上下文切換,導緻 CPU 幹正經事的時間少了,CPU 沒有充分利用,是不可取的。

注意:這兩個值越大,則由核心消耗的 CPU 就越多。

CPU

us:表示使用者程序消耗的 CPU 時間百分比,us 值越高,說明使用者程序消耗 CPU 時間越多,如果長期大于 50%,則需要考慮優化程式或者算法。sy:表示系統核心程序消耗的 CPU 時間百分比,一般來說 us+sy 應該小于 80%,如果大于 80%,說明可能存在 CPU 瓶頸。id:表示 CPU 處在空間狀态的時間百分比。wa:表示 IP 等待所占用的 CPU 時間百分比,wa 值越高,說明 I/O 等待越嚴重,根據經驗 wa 的參考值為 20%,如果超過 20%,說明 I/O 等待嚴重,引起 I/O 等待的原因可能是磁盤大量随機讀寫造成的,也可能是磁盤或者監控器的貸款瓶頸(主要是塊操作)造成的。

sar

sar 和 free 類似 sar -r 3 每隔三秒輸出一次記憶體資訊:

[root@localhost ~]# sar -r 3
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain)    2020年04月28日  _x86_64_        (2 CPU)

15時40分10秒 kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
15時40分13秒    106800   1314960     92.49      2144    573248   4110864    116.82    563664    498888        36
15時40分16秒    106816   1314944     92.49      2144    573248   4110864    116.82    563668    498888        36
15時40分19秒    106816   1314944     92.49      2144    573248   4110864    116.82    563668    498888        36
           

CPU 瓶頸

檢視機器 cpu 核數

CPU總核數 = 實體CPU個數 * 每顆實體CPU的核數 
總邏輯CPU數 = 實體CPU個數 * 每顆實體CPU的核數 * 超線程數
           

檢視 CPU 資訊(型号)

[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
     32  Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz
           

檢視實體 CPU 個數

[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
16
           

檢視每個實體 CPU 中 core 的個數 (即核數)

[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo| grep "cpu cores"| uniq
cpu cores       : 2
           

檢視邏輯 CPU 的個數

[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo| grep "processor"| wc -l
32
           

top

在 Linux 核心的作業系統中,程序是根據虛拟運作時間(由程序優先級、nice 值加上實際占用的 CPU 時間進行動态計算得出)進行動态排程的。在執行程序時,需要從使用者态轉換到核心态,使用者空間不能直接操作核心空間的函數。通常要利用系統調用來完成程序排程,而使用者空間到核心空間的轉換通常是通過軟中斷來完成的。例如要進行磁盤操作,使用者态需要通過系統調用核心的磁盤操作指令,是以 CPU 消耗的時間被切分成使用者态 CPU 消耗、系統(核心) CPU 消耗,以及磁盤操作 CPU 消耗。執行程序時,需要經過一系列的操作,程序首先在使用者态執行,在執行過程中會進行程序優先級的調整(nice),通過系統調用到核心,再通過核心調用,硬中斷、軟中斷,讓硬體執行任務。執行完成之後,再從核心态傳回給系統調用,最後系統調用将結果傳回給使用者态的程序。

top 可以檢視 CPU 總體消耗,包括分項消耗,如 User,System,Idle,nice 等。Shift + H 顯示 java 線程;Shift + M 按照記憶體使用排序;Shift + P 按照 CPU 使用時間(使用率)排序;Shift + T 按照 CPU 累積使用時間排序;多核 CPU,進入 top 視圖 1,可以看到各各 CPU 的負載情況。

top - 15:24:11 up 8 days,  7:52,  1 user,  load average: 5.73, 6.85, 7.33
Tasks:  17 total,   1 running,  16 sleeping,   0 stopped,   0 zombie
%Cpu(s): 13.9 us,  9.2 sy,  0.0 ni, 76.1 id,  0.1 wa,  0.0 hi,  0.1 si,  0.7 st
KiB Mem : 11962365+total, 50086832 free, 38312808 used, 31224016 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 75402760 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
   300 ymmapp    20   0 17.242g 1.234g  14732 S   2.3  1.1   9:40.38 java
     1 root      20   0   15376   1988   1392 S   0.0  0.0   0:00.06 sh
    11 root      20   0  120660  11416   1132 S   0.0  0.0   0:04.94 python
    54 root      20   0   85328   2240   1652 S   0.0  0.0   0:00.00 su
    55 ymmapp    20   0   17432   1808   1232 S   0.0  0.0   0:00.00 bash
    56 ymmapp    20   0   17556   2156   1460 S   0.0  0.0   0:00.03 control.sh
    57 ymmapp    20   0   11880    740    576 S   0.0  0.0   0:00.00 tee
   115 ymmapp    20   0   17556   2112   1464 S   0.0  0.0   0:00.02 control_new_war
   133 root      20   0  106032   4240   3160 S   0.0  0.0   0:00.03 sshd
   134 ymmapp    20   0   17080   6872   3180 S   0.0  0.0   0:01.82 ops-updater
   147 ymmapp    20   0   17956   2636   1544 S   0.0  0.0   0:00.07 control.sh
  6538 ymmapp    20   0  115656  10532   3408 S   0.0  0.0   0:00.46 beidou-agent
  6785 ymmapp    20   0 2572996  22512   2788 S   0.0  0.0   0:03.44 gatherinfo4dock
 29241 root      20   0  142148   5712   4340 S   0.0  0.0   0:00.04 sshd
 29243 1014154   20   0  142148   2296    924 S   0.0  0.0   0:00.00 sshd
 29244 1014154   20   0   15208   2020   1640 S   0.0  0.0   0:00.00 bash
 32641 1014154   20   0   57364   2020   1480 R   0.0  0.0   0:00.00 top
           

第一行:15:24:11 up 8 days, 7:52, 1 user, load average: 5.73, 6.85, 7.33:15:24:11 系統時間,up 8 days 運作時間,1 user 目前登入使用者數,load average 負載均衡情況,分别表示 1 分鐘,5 分鐘,15 分鐘負載情況。

第二行:Tasks: 17 total, 1 running, 16 sleeping, 0 stopped, 0 zombie:總程序數 17,運作數 1,休眠 16,停止 0,僵屍程序 0。

第三行:%Cpu(s): 13.9 us, 9.2 sy, 0.0 ni, 76.1 id, 0.1 wa, 0.0 hi, 0.1 si, 0.7 st:使用者空間 CPU 占比 13.9%,核心空間 CPU 占比 9.2%,改變過優先級的程序 CPU 占比 0%,空閑 CPU 占比 76.1,IO 等待占用 CPU 占比 0.1%,硬中斷占用 CPU 占比 0%,軟中斷占用 CPU 占比 0.1%, 目前 VM 中的 cpu 時鐘被虛拟化偷走的比例 0.7%。

第四和第五行表示記憶體和 swap 區域的使用情況。

第七行表示:

  • PID: 程序 id
  • USER: 程序所有者
  • PR: 程序優先級
  • NI:nice 值。負值表示高優先級,正值表示低優先級
  • VIRT: 虛拟記憶體,程序使用的虛拟記憶體總量,機關 kb。VIRT=SWAP+RES
  • RES: 常駐記憶體,程序使用的、未被換出的實體記憶體大小,機關 kb。RES=CODE+DATA
  • SHR: 共享記憶體,共享記憶體大小,機關 kb
  • S: 程序狀态。D = 不可中斷的睡眠狀态 R = 運作 S = 睡眠 T = 跟蹤 / 停止 Z = 僵屍程序
  • %CPU : 上次更新到現在的 CPU 時間占用百分比
  • %MEM : 程序使用的實體記憶體百分比
  • TIME+ : 程序使用的 CPU 時間總計,機關 1/100 秒
  • COMMAND : 程序名稱(指令名 / 指令行)

計算在 cpu load 裡面的 uninterruptedsleep 的任務數量

top -b -n 1 | awk '{if (NR<=7)print;else if($8=="D"){print;count++}}END{print "Total status D:"count}'
[root@localhost ~]# top -b -n 1 | awk '{if (NR<=7)print;else if($8=="D"){print;count++}}END{print "Total status D:"count}'
top - 15:35:05 up 1 day, 26 min,  3 users,  load average: 0.00, 0.01, 0.05
Tasks: 225 total,   1 running, 224 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.5 us, 10.0 sy,  0.0 ni, 87.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1421760 total,   104516 free,   777344 used,   539900 buff/cache
KiB Swap:  2097148 total,  2071152 free,    25996 used.   456028 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
Total status D:
           

sar

通過 sar -u 3 可以檢視 CUP 總體消耗占比:

[root@localhost ~]# sar -u 3
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain)    2020年05月01日  _x86_64_        (2 CPU)

15時18分03秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
15時18分06秒     all      0.00      0.00      0.17      0.00      0.00     99.83
15時18分09秒     all      0.00      0.00      0.17      0.00      0.00     99.83
15時18分12秒     all      0.17      0.00      0.17      0.00      0.00     99.66
15時18分15秒     all      0.00      0.00      0.00      0.00      0.00    100.00
15時18分18秒     all      0.00      0.00      0.00      0.00      0.00    100.00
           
  • %user:使用者空間的 CPU 使用。
  • %nice:改變過優先級的程序的 CPU 使用率。
  • %system:核心空間的 CPU 使用率。
  • %iowait:CPU 等待 IO 的百分比 。
  • %steal:虛拟機的虛拟機 CPU 使用的 CPU。
  • %idle:空閑的 CPU。

    在以上的顯示當中,主要看 %iowait 和 %idle:

  • 若 %iowait 的值過高,表示硬碟存在 I/O 瓶頸;
  • 若 %idle 的值高但系統響應慢時,有可能是 CPU 等待配置設定記憶體,此時應加大記憶體容量;
  • 若 %idle 的值持續低于 10,則系統的 CPU 處理能力相對較低,表明系統中最需要解決的資源是 CPU;

定位線上最耗 CPU 的線程

準備工作

啟動一個程式。arthas-demo 是一個簡單的程式,每隔一秒生成一個随機數,再執行質因數分解,并列印出分解結果。

curl -O https://alibaba.github.io/arthas/arthas-demo.jar
java -jar arthas-demo.jar
[root@localhost ~]# curl -O https://alibaba.github.io/arthas/arthas-demo.jar
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3743  100  3743    0     0   3022      0  0:00:01  0:00:01 --:--:--  3023
[root@localhost ~]# java -jar arthas-demo.jar
1813=7*7*37
illegalArgumentCount:  1, number is: -180005, need >= 2
illegalArgumentCount:  2, number is: -111175, need >= 2
18505=5*3701
166691=7*23813
105787=11*59*163
60148=2*2*11*1367
196983=3*3*43*509
illegalArgumentCount:  3, number is: -173479, need >= 2
illegalArgumentCount:  4, number is: -112840, need >= 2
39502=2*19751
....
           

通過 top 指令找到最耗時的程序

[root@localhost ~]# top
top - 11:11:05 up 20:02,  3 users,  load average: 0.09, 0.07, 0.05
Tasks: 225 total,   1 running, 224 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.7 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1421760 total,   135868 free,   758508 used,   527384 buff/cache
KiB Swap:  2097148 total,  2070640 free,    26508 used.   475852 avail Mem
Change delay from 3.0 to
   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 98344 root      20   0 2422552  23508  12108 S   0.7  1.7   0:00.32 java
     1 root      20   0  194100   6244   3184 S   0.0  0.4   0:20.41 systemd
     2 root      20   0       0      0      0 S   0.0  0.0   0:00.12 kthreadd
     4 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H
     6 root      20   0       0      0      0 S   0.0  0.0   0:20.25 ksoftirqd/0
           

找到程序号是 98344。

找到程序中最耗 CUP 的線程

使用 ps -Lp #pid cu 指令,檢視某個程序中的線程 CPU 消耗排序:

[root@localhost ~]# ps -Lp 98344 cu
USER        PID    LWP %CPU NLWP %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      98344  98344  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:00 java
root      98344  98345  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:04 java
root      98344  98346  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:01 VM Thread
root      98344  98347  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:00 Reference Handl
root      98344  98348  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:00 Finalizer
root      98344  98349  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:00 Signal Dispatch
root      98344  98350  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:05 C2 CompilerThre
root      98344  98351  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:00 C1 CompilerThre
root      98344  98352  0.0   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:00 Service Thread
root      98344  98353  0.1   10  4.1 2422552 59060 pts/0   Sl+  11:09   0:19 VM Periodic Tas
           

看 TIME 列可以看出那個線程耗費 CUP 多,根據 LWP 列可以看到線程的 ID 号,但是需要轉換成 16 進制才可以查詢線程堆棧資訊。

擷取線程 id 的十六進制碼

使用 printf '%x\n' 98345 指令做進制轉換:

[root@localhost ~]# printf '%x\n' 98345
18029
           

檢視線程堆棧資訊

使用 jstack 擷取堆棧資訊 jstack 98344 | grep -A 10 18029:

[root@localhost ~]# jstack 98344 | grep -A 10 18029
"main" #1 prio=5 os_prio=0 tid=0x00007fb88404b800 nid=0x18029 waiting on condition [0x00007fb88caab000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at demo.MathGame.main(MathGame.java:17)

"VM Thread" os_prio=0 tid=0x00007fb8840f2800 nid=0x1802a runnable

"VM Periodic Task Thread" os_prio=0 tid=0x00007fb884154000 nid=0x18031 waiting on condition
           

通過指令我們可以看到這個線程的對應的耗時代碼是在 demo.MathGame.main(MathGame.java:17)

grep -C 5 foo file 顯示file檔案裡比對foo字串那行以及上下5行
grep -B 5 foo file 顯示foo及前5行
grep -A 5 foo file 顯示foo及後5行
           

網絡瓶頸

定位丢包,錯包情況

watch more /proc/net/dev 用于定位丢包,錯包情況,以便看網絡瓶頸,重點關注 drop (包被丢棄) 和網絡包傳送的總量,不要超過網絡上限:

[root@localhost ~]# watch -n 2 more /proc/net/dev
Every 2.0s: more /proc/net/dev                                                                                                                                                   Fri May  1 17:16:55 2020

Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:   10025     130    0    0    0     0          0         0    10025     130    0    0    0     0       0          0
 ens33: 759098071  569661    0    0    0     0          0         0 19335572  225551    0    0    0     0       0          0
           
  • 最左邊的表示接口的名字,Receive 表示收包,Transmit 表示發送包;
  • bytes:表示收發的位元組數;
  • packets:表示收發正确的包量;
  • errs:表示收發錯誤的包量;
  • drop:表示收發丢棄的包量;

檢視路由經過的位址

traceroute ip 可以檢視路由經過的位址,常用來統計網絡在各個路由區段的耗時,如:

[root@localhost ~]# traceroute 14.215.177.38
traceroute to 14.215.177.38 (14.215.177.38), 30 hops max, 60 byte packets
 1  CD-HZTK5H2.mshome.net (192.168.137.1)  0.126 ms * *
 2  * * *
 3  10.250.112.3 (10.250.112.3)  12.587 ms  12.408 ms  12.317 ms
 4  172.16.227.230 (172.16.227.230)  2.152 ms  2.040 ms  1.956 ms
 5  172.16.227.202 (172.16.227.202)  11.884 ms  11.746 ms  12.692 ms
 6  172.16.227.65 (172.16.227.65)  2.665 ms  3.143 ms  2.923 ms
 7  171.223.206.217 (171.223.206.217)  2.834 ms  2.752 ms  2.654 ms
 8  182.150.18.205 (182.150.18.205)  5.145 ms  5.815 ms  5.542 ms
 9  110.188.6.33 (110.188.6.33)  3.514 ms 171.208.199.185 (171.208.199.185)  3.431 ms 171.208.199.181 (171.208.199.181)  10.768 ms
10  202.97.29.17 (202.97.29.17)  29.574 ms 202.97.30.146 (202.97.30.146)  32.619 ms *
11  113.96.5.126 (113.96.5.126)  36.062 ms 113.96.5.70 (113.96.5.70)  35.940 ms 113.96.4.42 (113.96.4.42)  45.859 ms
12  90.96.135.219.broad.fs.gd.dynamic.163data.com.cn (219.135.96.90)  35.680 ms  35.468 ms  35.304 ms
13  14.215.32.102 (14.215.32.102)  35.135 ms 14.215.32.110 (14.215.32.110)  35.613 ms 14.29.117.242 (14.29.117.242)  54.712 ms
14  * 14.215.32.134 (14.215.32.134)  49.518 ms 14.215.32.122 (14.215.32.122)  47.652 ms
15  * * *
...
           

檢視網絡錯誤

netstat -i 可以檢視網絡錯誤:

[root@localhost ~]# netstat -i
Kernel Interface table
Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
ens33            1500   570291      0      0 0        225897      0      0      0 BMRU
lo              65536      130      0      0 0           130      0      0      0 LRU
           
  • Iface: 網絡接口名稱;
  • MTU: 最大傳輸單元,它限制了資料幀的最大長度,不同的網絡類型都有一個上限值,如:以太網的 MTU 是 1500;
  • RX-OK:接收時,正确的資料包數。
  • RX-ERR``==:接收時,産生錯誤的資料包數。
  • RX-DRP:接收時,丢棄的資料包數。
  • RX-OVR:接收時,由于過速(在資料傳輸中,由于接收裝置不能接收按照發送速率傳送來的資料而使資料丢失)而丢失的資料包數。
  • TX-OK:發送時,正确的資料包數。
  • TX-ERR:發送時,産生錯誤的資料包數。
  • TX-DRP:發送時,丢棄的資料包數。
  • TX-OVR:發送時,由于過速而丢失的資料包數。
  • Flg:标志,B 已經設定了一個廣播位址。L 該接口是一個回送裝置。M 接收所有資料包(混亂模式)。N 避免跟蹤。O 在該接口上,禁用 ARP。P 這是一個點到點連結。R 接口正在運作。U 接口處于 “活動” 狀态。

包的重傳率

cat /proc/net/snmp 用來檢視和分析 240 秒内網絡包量,流量,錯包,丢包。通過 RetransSegs 和 OutSegs 來計算重傳率 tcpetr=RetransSegs/OutSegs。

[root@localhost ~]# cat /proc/net/snmp
Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
Ip: 1 64 241708 0 0 0 0 0 238724 225517 15 0 0 0 0 0 0 0 0
Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
Icmp: 149 0 0 50 99 0 0 0 0 0 0 0 0 0 147 0 147 0 0 0 0 0 0 0 0 0 0
IcmpMsg: InType3 InType11 OutType3
IcmpMsg: 50 99 147
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
Tcp: 1 200 120000 -1 376 6 0 0 4 236711 223186 292 0 4 0
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
Udp: 1405 438 0 1896 0 0 0
UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
UdpLite: 0 0 0 0 0 0 0
           

重傳率 = 292/223186≈0.13%

  • 平均每秒新增 TCP 連接配接數:通過 /proc/net/snmp 檔案得到最近 240 秒内 PassiveOpens 的增量,除以 240 得到每秒的平均增量;
  • 機器的 TCP 連接配接數 :通過 /proc/net/snmp 檔案的 CurrEstab 得到 TCP 連接配接數;
  • 平均每秒的 UDP 接收資料報:通過 /proc/net/snmp 檔案得到最近 240 秒内 InDatagrams 的增量,除以 240 得到平均每秒的 UDP 接收資料報;
  • 平均每秒的 UDP 發送資料報:通過 /proc/net/snmp 檔案得到最近 240 秒内 OutDatagrams 的增量,除以 240 得到平均每秒的 UDP 發送資料報;

磁盤瓶頸

檢視磁盤剩餘空間

檢視磁盤剩餘空間使用 df -hl 指令:

[root@localhost ~]# df -hl
檔案系統                       容量  已用  可用 已用% 挂載點
devtmpfs                       678M     0  678M    0% /dev
tmpfs                          695M     0  695M    0% /dev/shm
tmpfs                          695M   28M  667M    4% /run
tmpfs                          695M     0  695M    0% /sys/fs/cgroup
/dev/mapper/centos_aubin-root   27G  5.6G   22G   21% /
/dev/sda1                     1014M  211M  804M   21% /boot
           

檢視磁盤已使用空間

du -sh 指令是檢視磁盤已使用空間的情況,這裡的 “已使用的磁盤空間” 意思是指定的檔案下的整個檔案層次結構所使用的空間,在沒給定參數的情況下,du 報告目前目錄所使用的磁盤空間。其實就是顯示檔案或目錄所占用的磁盤空間的情況:

[root@localhost ~]# du -sh
64K  
           
  • -h:輸出檔案系統分區使用的情況,例如:10KB,10MB,10GB 等。
  • -s:顯示檔案或整個目錄的大小,預設機關是 KB。

du 的詳細資訊可以通過 man du 檢視。

檢視磁盤讀寫情況

檢視磁盤總體讀寫情況

通 iostat 檢視磁盤總體的讀寫情況:

[root@localhost ~]# iostat
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain)    2020年05月02日  _x86_64_        (2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.17    0.00    0.20    0.46    0.00   99.17

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               1.56        30.45        39.61    4659620    6060644
scd0              0.00         0.02         0.00       3102          0
dm-0              1.96        30.01        38.42    4591998    5878155
dm-1              0.09         0.09         0.30      13840      45328
           
  • tps:該裝置每秒的傳輸次數。
  • kB_read/s:每秒從裝置(drive expressed)讀取的資料量;
  • kB_wrtn/s:每秒向裝置(drive expressed)寫入的資料量;
  • kB_read:讀取的總資料量;
  • kB_wrtn:寫入的總數量資料量;

檢視磁盤詳細讀寫情況

通過 iostat -x 1 3 可以看到磁盤詳細讀寫情況,沒隔一秒輸出一次一共輸出 3 次,當看到 I/O 等待時間所占 CPU 時間的比重很高的時候,首先要檢查的就是機器是否正在大量使用交換空間,同時關注 iowait 占比 cpu 的消耗是否很大,如果大說明磁盤存在大的瓶頸,同時關注 await,表示磁盤的響應時間以便小于 5ms:

[root@localhost ~]# iostat -x 1 3
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain)    2020年05月02日  _x86_64_        (2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.17    0.00    0.20    0.46    0.00   99.16

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.01     0.49    0.63    0.95    30.59    39.78    89.58     0.34  214.23   49.16  323.48   8.55   1.34
scd0              0.00     0.00    0.00    0.00     0.02     0.00    98.48     0.00    1.21    1.21    0.00   0.95   0.00
dm-0              0.00     0.00    0.62    1.35    30.15    38.59    69.70     0.91  460.67   49.12  648.54   6.66   1.31
dm-1              0.00     0.00    0.02    0.07     0.09     0.30     8.52     0.04  442.74   95.43  521.17   6.91   0.06
           

avg-cpu 表示總體 cpu 使用情況統計資訊,對于多核 cpu,這裡為所有 cpu 的平均值:

  • %user:CPU 處在使用者模式下的時間百分比。
  • %nice:CPU 處在帶 NICE 值的使用者模式下的時間百分比。
  • %system:CPU 處在系統模式下的時間百分比。
  • %iowait:CPU 等待輸入輸出完成時間的百分比,如果 % iowait 的值過高,表示硬碟存在 I/O 瓶頸。
  • %steal:管理程式維護另一個虛拟處理器時,虛拟 CPU 的無意識等待時間百分比。
  • %idle:CPU 空閑時間百分比,如果 % idle 值高,表示 CPU 較空閑;如果 % idle 值高但系統響應慢時,可能是 CPU 等待配置設定記憶體,應加大記憶體容量;如果 % idle 值持續低于 10,表明 CPU 處理能力相對較低,系統中最需要解決的資源是 CPU。。

Device 表示裝置資訊:

  • rrqm/s:每秒對該裝置的讀請求被合并次數,檔案系統會對讀取同塊 (block) 的請求進行合并
  • wrqm/s:每秒對該裝置的寫請求被合并次數
  • r/s:每秒完成的讀次數
  • w/s:每秒完成的寫次數
  • rkB/s:每秒讀資料量 (kB 為機關)
  • wkB/s:每秒寫資料量 (kB 為機關)
  • avgrq-sz:平均每次 IO 操作的資料量 (扇區數為機關)
  • avgqu-sz:平均等待處理的 IO 請求隊列長度
  • await:平均每次 IO 請求等待時間 (包括等待時間和處理時間,毫秒為機關)
  • svctm:平均每次 IO 請求的處理時間 (毫秒為機關)
  • %util:一秒中有百分之多少的時間用于 I/O 如果 % util 接近 100%,說明産生的 I/O 請求太多,I/O 系統已經滿負荷。idle 小于 70% IO 壓力就較大了,一般讀取速度有較多的 wait。

iostat -xmd 1 3:新增 m 選項可以在輸出是使用 M 為機關。

檢視最耗 IO 的程序

一般先通過 iostat 檢視是否存在 io 瓶頸,再使用 iotop 指令來定位那個程序最耗費 IO:

[root@localhost ~]# iotop
Total DISK READ :       0.00 B/s | Total DISK WRITE :       0.00 B/s
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       0.00 B/s
   TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
123931 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.02 % [kworker/1:30]
 94208 be/4 xiaolyuh    0.00 B/s    0.00 B/s  0.00 %  0.00 % nautilus-desktop --force [gmain]
     1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % systemd --system --deserialize 62
     2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
 94211 be/4 xiaolyuh    0.00 B/s    0.00 B/s  0.00 %  0.00 % gvfsd-trash --spawner :1.4 /org/gtk/gvfs/exec_spaw/0
     4 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/0:0H]
     6 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
     7 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/0]
     8 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_bh]
     9 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_sched]
    10 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [lru-add-drain]
...
           

通過 iotop -p pid 可以檢視單個程序的 IO 情況:

[root@localhost ~]# iotop -p 124146
Total DISK READ :       0.00 B/s | Total DISK WRITE :       0.00 B/s
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       0.00 B/s
   TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
124146 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % java -jar arthas-demo.jar
           

應用瓶頸

檢視某個程序的 PID

如檢視 java 的程序的 pid,ps -ef | grep java:

[root@localhost ~]# ps -ef | grep java
root     124146   1984  0 09:13 pts/0    00:00:06 java -jar arthas-demo.jar
root     125210  98378  0 10:07 pts/1    00:00:00 grep --color=auto java
           

檢視特定程序的數量

如檢視 java 程序的數量,ps -ef | grep java| wc -l:

[root@localhost ~]# ps -ef | grep java| wc -l
2
           

檢視線程是否存在死鎖

檢視線程是否存在死鎖,jstack -l pid:

[root@localhost ~]# jstack -l 124146
2020-05-02 10:13:38
Full thread dump OpenJDK 64-Bit Server VM (25.252-b09 mixed mode):

"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f27f013c000 nid=0x1e4f9 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f27f012d000 nid=0x1e4f8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"main" #1 prio=5 os_prio=0 tid=0x00007f27f004b800 nid=0x1e4f3 waiting on condition [0x00007f27f7274000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at demo.MathGame.main(MathGame.java:17)

   Locked ownable synchronizers:
        - None
...
           

檢視某個程序的線程數

ps -efL | grep [PID] | wc -l,如:

[root@localhost ~]# ps -efL | grep 124146 | wc -l
12
           

檢視具體有哪些線程用 ps -Lp [pid] cu:

[root@localhost ~]# ps -Lp 124146 cu
USER        PID    LWP %CPU NLWP %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     124146 124146  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 java
root     124146 124147  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:01 java
root     124146 124148  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 VM Thread
root     124146 124149  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 Reference Handl
root     124146 124150  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 Finalizer
root     124146 124151  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 Signal Dispatch
root     124146 124152  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 C2 CompilerThre
root     124146 124153  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 C1 CompilerThre
root     124146 124154  0.0   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:00 Service Thread
root     124146 124155  0.1   11  2.5 2489116 35724 pts/0   Sl+  09:13   0:05 VM Periodic Tas
root     124146 125362  0.0   11  2.5 2489116 35724 pts/0   Sl+  10:13   0:00 Attach Listener
           

統計所有的 log 檔案中,包含 Error 字元的行

find / -type f -name "*.log" | xargs grep "ERROR",這個在排查問題過程中比較有用:

[root@localhost ~]# find / -type f -name "*.log" | xargs grep "ERROR"
/var/log/tuned/tuned.log:2020-03-13 18:05:59,145 ERROR    tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-03-13 18:05:59,145 ERROR    tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-04-28 14:55:34,857 ERROR    tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-04-28 14:55:34,859 ERROR    tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-04-28 15:23:19,037 ERROR    tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' error: '[Errno 19] No such device'
...
           

應用啟動時指定 JVM 參數

java -jar -Xms128m -Xmx1024m -Xss512k -XX:PermSize=128m -XX:MaxPermSize=64m -XX:NewSize=64m -XX:MaxNewSize=256m arthas-demo.jar,如:

[root@localhost ~]# java -jar -Xms128m -Xmx1024m -Xss512k -XX:PermSize=128m -XX:MaxPermSize=64m -XX:NewSize=64m -XX:MaxNewSize=256m  arthas-demo.jar
OpenJDK 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=64m; support was removed in 8.0
157518=2*3*3*3*2917
illegalArgumentCount:  1, number is: -187733, need >= 2
illegalArgumentCount:  2, number is: -102156, need >= 2
173379=3*57793
           

總結

在使用 linux 指令時,如果想看幫助可以使用 --help 或者 man 檢視幫助資訊:

[root@localhost ~]# grep --help
用法: grep [選項]... PATTERN [FILE]...
在每個 FILE 或是标準輸入中查找 PATTERN。
預設的 PATTERN 是一個基本正規表達式(縮寫為 BRE)。
例如: grep -i 'hello world' menu.h main.c
...
[root@localhost ~]# man grep

GREP(1)                                                        General Commands Manual                                                        GREP(1)

NAME
       grep, egrep, fgrep - 列印比對給定模式的行

總覽 SYNOPSIS
       grep [options] PATTERN [FILE...]
       grep [options] [-e PATTERN | -f FILE] [FILE...]

描述 DESCRIPTION
       Grep    搜尋以    FILE    命名的檔案輸入   (或者是标準輸入,如果沒有指定檔案名,或者給出的檔案名是   -   的話),尋找含有與給定的模式   PATTERN
...
           
類别 監控指令 描述 備注
記憶體瓶頸 free 檢視記憶體使用
vmstat 3 (間隔時間) 100 (監控次數) 檢視 swap in/out 詳細定位是否存在性能瓶頸 推薦使用
sar -r 3 和 free 指令類似,檢視記憶體的使用情況,但是不包含 swap 的情況
cpu 瓶頸 top -H 按照 cpu 消耗高低進行排序
ps -Lp 程序号 cu 檢視某個程序的 cpu 消耗排序
cat /proc/cpuinfo |grep ‘processor’|wc -l 檢視 cpu 核數
top 檢視 cpu 總體消耗,包括分項消耗如 user,system,idle,nice 等消耗
top 然後 shift+h: 顯示 java 線程,然後 shift+M: 按照記憶體使用進行排序;shift+P: 按照 cpu 時間排序;shift+T: 按照 cpu 累計使用時間排序多核 cpu,按 “1” 進入 top 視圖 專項性能排查,多核 CPU 主要看 CUP 各個核心的負載情況
sar -u 3 (間隔時間) 檢視 cpu 總體消耗占比
sar -q 檢視 cpu load
top -b -n 1 | awk ‘{if (NR<=7)print;else if($8==“D”){print;count++}}END{print "Total status D:"count}’ 計算在 cpu load 裡面的 uninterruptedsleep 的任務數量 uninterruptedsleep 的任務會被計入 cpu load,如磁盤堵塞
網絡瓶頸 cat /var/log/messages 檢視核心日志,檢視是否丢包
watch more /proc/net/dev 用于定位丢包,錯包情況,以便看網絡瓶頸 重點關注 drop (包被丢棄) 和網絡包傳送的總量,不要超過網絡上限
sar -n SOCK 檢視網絡流量
netstat -na|grep ESTABLISHED|wc -l 檢視 tcp 連接配接成功狀态的數量 此指令特别消耗 cpu,不适合進行長時間監控資料收集
netstat -na|awk’{print $6}'|sort |uniq -c |sort -nr 看 tcp 各個狀态數量
netstat -i 檢視網絡錯誤
ss state ESTABLISHED| wc -l 更高效地統計 tcp 連接配接狀态為 ESTABLISHED 的數量
cat /proc/net/snmp 檢視和分析 240 秒内網絡包量,流量,錯包,丢包 用于計算重傳率 tcpetr=RetransSegs/OutSegs
ping $ip 測試網絡性能
dmesg 檢視系統核心日志
磁盤瓶頸 iostat -x -k -d 1 詳細列出磁盤的讀寫情況 當看到 I/O 等待時間所占 CPU 時間的比重很高的時候,首先要檢查的就是機器是否正在大量使用交換空間,同時關注 iowait 占比 cpu 的消耗是否很大,如果大說明磁盤存在大的瓶頸,同時關注 await,表示磁盤的響應時間以便小于 5ms
iostat -x 檢視系統各個磁盤的讀寫性能 重點關注 await 和 iowait 的 cpu 占比
iotop 檢視哪個程序在大量讀取 IO 一般先通過 iostat 檢視是否存在 io 瓶頸,再定位哪個程序在大量讀取 IO
df -hl 檢視磁盤剩餘空間
du -sh 檢視磁盤使用了多少空間
應用瓶頸 ps -ef grep java 檢視某個程序的 id 号
ps -ef | grep httpd| wc -l 檢視特定程序的數量
cat ***.log | grep ***Exception| wc -l 統計日志檔案中包含特定異常數量
jstack -l pid 用于檢視線程是否存在死鎖
awk’{print $8}’ 2017-05-22-access_log|egrep ‘301|302’| wc -l 統計 log 中 301、302 狀态碼的行數,$8 表示第八列是狀态碼,可以根據實際情況更改 常用于應用故障定位
grep ‘wholesaleProductDetailNew’ cookie_log | awk '{if($10==“200”)}‘print}’ awk ‘print $12’ | more 列印包含特定資料的 12 列資料
grep “2017:05:22” cookielog | awk ‘($12>0.3){print 8}’ | sort > 目錄位址 對 apache 或者 nginx 通路 log 進行響應時間排序,$12 表示 cookie log 中的 12 清單示響應時間 用于排查是否是由于是某些通路超長造成整體的 RT 變長
grep -v ‘HTTP/1.1" 200’ 取出非 200 響應碼的 URL
pgm -A -f $ 應用叢集名稱 “grep”‘301’ log 檔案位址 | wc -l" 檢視整個叢集的 log 中 301 狀态碼的數量
ps -efL | grep [PID] | wc -l 檢視某個程序建立的線程數
find / -type f -name “*.log” | xargs grep “ERROR” 統計所有的 log 檔案中,包含 Error 字元的行 這個在排查問題過程中比較有用
jstat -gc [pid] 檢視 gc 情況
jstat -gcnew [pid] 檢視 young 區的記憶體使用情況,包括 MTT (最大互動次數就被交換到 old 區),TT 是目前已經交換的次數
jstat -gcold 檢視 old 區的記憶體使用情況
jmap -J-d64 -dump:format=b,file=dump.bin PID dump 出記憶體快照 -J-d64 防止 jmap 導緻虛拟機 crash (jdk6 有 bug)
-XX:+HeapDumpOnOutOfMemeryError 在 java 啟動時加入,當出現記憶體溢出時,存儲記憶體快照
jmap -histo [pid] 按照對象記憶體大小排序 注意會導緻 full gc
gcore [pid] 導出完成的記憶體快照 通常和 jmap -permstat /opt/**/java gcore.bin 一起使用,将 core dump 轉換成 heap dump
-XX:HeapDumpPath=/home/logs -Xloggc:/home/log/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps 在 Java 啟動參數中加入,列印 gc 日志
-server -Xms4000m -Xmx4000m -Xmn1500m -Xss256k -XX:PermSize=340m -XX:MaxPermSize=340m -XX:+UseConcMarkSweepGC 調整 JVM 堆大小 xss 是棧大小

繼續閱讀