topコマンドでswap表示

2021年6月14日

前回は仮想メモリを調査し、使用されて始めて実メモリを確保することが明確になりました。そして純粋にメモリという意味では、psコマンドのVSZ(やSZ)はさして有用ではなく、RSSと出来ればswapが欲しいな…でもpsコマンドではswapは出せず、proc filesystemの力を借りていました。原始的ですね。

それならば…と今回はリアルタイムpsとも言うべきtopコマンドの出番です。bsdの呪いを解いたのも束の間、実はPOSIX標準の呪いにかかっていたpsコマンドを救うために、標準に縛られないニューヒーローtopコマンドにスポットライトを当てます。

topコマンドとは

top - 07:15:28 up 4 days, 14:36,  1 user,  load average: 0.00, 0.03, 0.16
Tasks: 205 total,   1 running, 204 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.0 us,  0.3 sy,  0.0 ni, 97.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3936.4 total,    803.9 free,   1868.1 used,   1264.4 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1705.4 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                               
   1991 user      20   0  778316  63316  22116 S   1.0   1.6   3:01.12 qterminal                                                                                                             
   1530 root      20   0  590156  74928  32984 S   0.7   1.9  16:56.18 Xorg                                                                                                                  
 128291 user      20   0   53.7g 692064 165300 S   0.7  17.2  10:01.78 chrome                                                                                                                
   1228 systemd+  20   0 1609028  80200   6676 S   0.3   2.0  25:41.02 mongod                                                                                                                
  44524 user      20   0  934844 146112   8016 S   0.3   3.6   9:51.34 gitea                                                                                                                 
 128482 user      20   0   37.2g 122680  84460 S   0.3   3.0   0:10.28 chrome                                                                                                                
 129541 user      20   0   13008   3864   3080 R   0.3   0.1   0:00.02 top                                                                                                                   
      1 root      20   0  169184   9392   4392 S   0.0   0.2   0:06.09 systemd      

こんな画面のやつです。最右列のコマンドで起動したプロセスの各属性、PIDとか実行ユーザーとか、使用メモリとか見れます。ここまではpsと同じですが、topはこの画面を(デフォルトでは)3秒おきに書き換えます。リアルタイムに各プロセスの属性を確認できるわけです。このプロセスが急にCPUを使い始めたとか、そういうのに気づける優れものです。psより進化してますね。ただ万能というわけではなく、リアルタイムであるために1画面分しか見れません。使い方としては、特定のソート方法で並べ、例えば各プロセスのCPU使用率ランキングをリアルタイムで見る、みたいなことをします。

topコマンドのカスタマイズ

topコマンドは基本的にコマンドライン引数からカスタマイズするのではなく、起動後の画面でキーボード操作することで設定を変更し、その設定をファイルに保存することでカスタマイズします。およその操作方法は、「?」を押すことで見ることが出来ます。

Help for Interactive Commands - procps-ng UNKNOWN
Window 1:Def: Cumulative mode Off.  System: Delay 3.0 secs; Secure mode Off.

  Z,B,E,e   Global: 'Z' colors; 'B' bold; 'E'/'e' summary/task memory scale
  l,t,m     Toggle Summary: 'l' load avg; 't' task/cpu stats; 'm' memory info
  0,1,2,3,I Toggle: '0' zeros; '1/2/3' cpus or numa node views; 'I' Irix mode
  f,F,X     Fields: 'f'/'F' add/remove/order/sort; 'X' increase fixed-width

  L,&,<,> . Locate: 'L'/'&' find/again; Move sort column: '<'/'>' left/right
  R,H,J,C . Toggle: 'R' Sort; 'H' Threads; 'J' Num justify; 'C' Coordinates
  c,i,S,j . Toggle: 'c' Cmd name/line; 'i' Idle; 'S' Time; 'j' Str justify
  x,y     . Toggle highlights: 'x' sort field; 'y' running tasks
  z,b     . Toggle: 'z' color/mono; 'b' bold/reverse (only if 'x' or 'y')
  u,U,o,O . Filter by: 'u'/'U' effective/any user; 'o'/'O' other criteria
  n,#,^O  . Set: 'n'/'#' max tasks displayed; Show: Ctrl+'O' other filter(s)
  V,v     . Toggle: 'V' forest view; 'v' hide/show forest view children

  k,r       Manipulate tasks: 'k' kill; 'r' renice
  d or s    Set update interval
  W,Y       Write configuration file 'W'; Inspect other output 'Y'
  q         Quit
          ( commands shown with '.' require a visible task display window ) 
Press 'h' or '?' for help with Windows,
Type 'q' or <Esc> to continue

私がよく使うのは、「<」「>」でソート列を移動する操作ですね。CPUとメモリを対象列にすることが多いです。これから説明する内容もこの画面で説明されています。一通り見たら、「q」で抜けます(topコマンドではどの画面からも抜けるときは「q」を押します)。

swap列、used列の追加

topの通常画面で「f」を押します。すると

Fields Management for window 1:Def, whose current sort field is %CPU
   Navigate with Up/Dn, Right selects for move then <Enter> or Left commits,
   'd' or <Space> toggles display, 's' sets sort.  Use 'q' or <Esc> to end!

* PID     = Process Id             TGID    = Thread Group Id     
* USER    = Effective User Name    OOMa    = OOMEM Adjustment    
* PR      = Priority               OOMs    = OOMEM Score current 
* NI      = Nice Value             ENVIRON = Environment vars    
* VIRT    = Virtual Image (KiB)    vMj     = Major Faults delta  
* RES     = Resident Size (KiB)    vMn     = Minor Faults delta  
* SHR     = Shared Memory (KiB)    USED    = Res+Swap Size (KiB) 
* S       = Process Status         nsIPC   = IPC namespace Inode 
* %CPU    = CPU Usage              nsMNT   = MNT namespace Inode 
* %MEM    = Memory Usage (RES)     nsNET   = NET namespace Inode 
* TIME+   = CPU Time, hundredths   nsPID   = PID namespace Inode 
* COMMAND = Command Name/Line      nsUSER  = USER namespace Inode
  PPID    = Parent Process pid     nsUTS   = UTS namespace Inode 
  UID     = Effective User Id      LXC     = LXC container name  
  RUID    = Real User Id           RSan    = RES Anonymous (KiB) 
  RUSER   = Real User Name         RSfd    = RES File-based (KiB)
  SUID    = Saved User Id          RSlk    = RES Locked (KiB)    
  SUSER   = Saved User Name        RSsh    = RES Shared (KiB)    
  GID     = Group Id               CGNAME  = Control Group name  
  GROUP   = Group Name             NU      = Last Used NUMA node 
  PGRP    = Process Group Id    
  TTY     = Controlling Tty     
  TPGID   = Tty Process Grp Id  
  SID     = Session Id          
  nTH     = Number of Threads   
  P       = Last Used Cpu (SMP) 
  TIME    = CPU Time            
  SWAP    = Swapped Size (KiB)  
  CODE    = Code Size (KiB)     
  DATA    = Data+Stack (KiB)    
  nMaj    = Major Page Faults   
  nMin    = Minor Page Faults   
  nDRT    = Dirty Pages Count   
  WCHAN   = Sleeping in Function
  Flags   = Task Flags <sched.h>
  CGROUPS = Control Groups      
  SUPGIDS = Supp Groups IDs     
  SUPGRPS = Supp Groups Names   

こんな画面になります。

矢印の上下でtop画面で表示可能な各項目を選択することができ、スペースキーで表示・非表示を切り替えることが可能です。

この項目の並びはそのままtop画面での表示順序になるのですが、順番も変えることができます。右矢印キーで現在の項目を「ドラッグ」することができ、そのまま上下キーで移動させられます。ここでいいかなという位置でEnterキーを押すと「ドロップ」でき、結果順番を変えることができます。

今回はRESの下に、SWAPとUSEDを移動させ、表示に切り替えればOKです。以下のような設定になります。

Fields Management for window 1:Def, whose current sort field is %CPU
   Navigate with Up/Dn, Right selects for move then <Enter> or Left commits,
   'd' or <Space> toggles display, 's' sets sort.  Use 'q' or <Esc> to end!

* PID     = Process Id             SUPGRPS = Supp Groups Names   
* USER    = Effective User Name    TGID    = Thread Group Id     
* PR      = Priority               OOMa    = OOMEM Adjustment    
* NI      = Nice Value             OOMs    = OOMEM Score current 
* VIRT    = Virtual Image (KiB)    ENVIRON = Environment vars    
* RES     = Resident Size (KiB)    vMj     = Major Faults delta  
* SWAP    = Swapped Size (KiB)     vMn     = Minor Faults delta  
* USED    = Res+Swap Size (KiB)    nsIPC   = IPC namespace Inode 
* SHR     = Shared Memory (KiB)    nsMNT   = MNT namespace Inode 
* S       = Process Status         nsNET   = NET namespace Inode 
* %CPU    = CPU Usage              nsPID   = PID namespace Inode 
* %MEM    = Memory Usage (RES)     nsUSER  = USER namespace Inode
* TIME+   = CPU Time, hundredths   nsUTS   = UTS namespace Inode 
* COMMAND = Command Name/Line      LXC     = LXC container name  
  PPID    = Parent Process pid     RSan    = RES Anonymous (KiB) 
  UID     = Effective User Id      RSfd    = RES File-based (KiB)
  RUID    = Real User Id           RSlk    = RES Locked (KiB)    
  RUSER   = Real User Name         RSsh    = RES Shared (KiB)    
  SUID    = Saved User Id          CGNAME  = Control Group name  
  SUSER   = Saved User Name        NU      = Last Used NUMA node 
  GID     = Group Id            
  GROUP   = Group Name          
  PGRP    = Process Group Id    
  TTY     = Controlling Tty     
  TPGID   = Tty Process Grp Id  
  SID     = Session Id          
  nTH     = Number of Threads   
  P       = Last Used Cpu (SMP) 
  TIME    = CPU Time            
  CODE    = Code Size (KiB)     
  DATA    = Data+Stack (KiB)    
  nMaj    = Major Page Faults   
  nMin    = Minor Page Faults   
  nDRT    = Dirty Pages Count   
  WCHAN   = Sleeping in Function
  Flags   = Task Flags <sched.h>
  CGROUPS = Control Groups      
  SUPGIDS = Supp Groups IDs   

この設定を「q」で抜けると…

top - 07:55:51 up 4 days, 15:16,  1 user,  load average: 0.02, 0.04, 0.01
Tasks: 206 total,   1 running, 205 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.0 us,  0.3 sy,  0.0 ni, 98.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3936.4 total,    770.0 free,   1874.8 used,   1291.6 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1696.3 avail Mem 

    PID USER      PR  NI    VIRT    RES   SWAP   USED    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                 
 128291 user      20   0   53.8g 694836      0 694836 165300 S   0.7  17.2  10:21.64 chrome                                                                                                  
 128482 user      20   0   37.2g 122240      0 122240  84460 S   0.7   3.0   0:19.96 chrome                                                                                                  
    626 message+  20   0    9036   4016     36   4052   1996 S   0.3   0.1   0:24.20 dbus-daemon                                                                                             
   1228 systemd+  20   0 1609028  80664    764  81428   6676 S   0.3   2.0  25:50.32 mongod                                                                                                  
   1991 user      20   0  778316  63316    136  63452  22116 S   0.3   1.6   3:06.09 qterminal                                                                                               
   2612 user      20   0   33.5g 259224      0 259224 102792 S   0.3   6.4  11:35.15 chrome                                                                                                  
  44524 user      20   0  934844 146112     64 146176   8016 S   0.3   3.6   9:57.20 gitea                                                                                                   
 128840 root      20   0       0      0      0      0      0 I   0.3   0.0   0:01.38 kworker/0:1-events                                                                                      
      1 root      20   0  169184   9392      0   9392   4392 S   0.0   0.2   0:06.12 systemd   

こんな感じで、SWAP列とUSED列が追加されます。SWAPは分かると思いますが、USEDはRSS+SWAPです。そう、私が見たかった数値はこれ(USED)なのです。

このままでは、設定が一時的なものになってしまいます。次回起動時にはデフォルトに戻っちゃうので、「(大文字の)W」で保存しておきます。設定が保存されるのは、~/.config/procps/toprcになります。

まとめ

psコマンドでは見れなかった各プロセスのswap使用状況、これが一覧で分かるようになり、しかもusedなる便利な情報も一目で分かり、サクっとソートしてリアルタイム監視もできるtopコマンド。優秀ですね。