概要
LinuxでWebサーバを運用していく中で気になるメモリの使用量。
「どのプロセスが一番メモリを消費しているのか?」
を調査してみます。
ワンライナーの設定
通例、メモリの使用量を見るのは
ps aux
とするのですが、
- 全ての情報が見えてしまうので探しにくい
- 単位が分からない
等の問題が発生します。そこで、
現在利用中のプロセスから、一番メモリを使用しているサービスを昇順で5つ抜き出し、そのメモリ量を見やすい形で成形するワンライナー
を生成AIにて作ってもらいます。(Gemini 2.5 Proを利用)
物理メモリ使用量(RSS: Resident Set Size)を基準にして、MB単位で表示するワンライナー
ps aux | tail -n +2 | sort -k 6 -rn | head -n 5 | sort -k 6 -n | awk '{cmd=""; for(i=11;i<=NF;i++){cmd=cmd" "$i}; printf "%10.2f MB %s\n", $6/1024, cmd}'
コマンドの解説
ps aux
- 現在実行中の全ユーザーのプロセスを詳細な情報付きで表示します。
tail -n +2
ps
コマンドが出力する結果の1行目(ヘッダー行)を除外し、2行目以降のプロセス情報のみを次のコマンドに渡します。
sort -k 6 -rn
- 6列目にある RSS(物理メモリ使用量) を基準に、数値を大きい順(降順)に並べ替えます。
-k 6
: 6列目をソートキーに指定します。-r
: 逆順(降順)でソートします。-n
: 文字列ではなく数値としてソートします。
head -n 5
- 降順にソートされた結果から、上位5つのプロセス(最もメモリを使用している5つ)を抽出します。
sort -k 6 -n
- 抽出された5つのプロセスを、再度6列目のRSSを基準に、今度は小さい順(昇順)に並べ替えます。
awk '{ ... }'
- 最終的な出力を見やすい形式に整形します。
cmd=""; for(i=11;i<=NF;i++){cmd=cmd" "$i}
: 11列目以降の文字列をすべて連結し、スペースを含む完全なコマンド名を変数cmd
に格納します。printf "%10.2f MB %s\n", $6/1024, cmd}
: 6列目のRSS(KB単位)を1024で割ってMB単位に変換し、小数点以下2桁までの浮動小数点数としてフォーマットします。メモリ量を右寄せ10桁で表示した後、コマンド名を表示します。
表示例
ps aux | tail -n +2 | sort -k 6 -rn | head -n 5 | sort -k 6 -n | awk '{cmd=""; for(i=11;i<=NF;i++){cmd=cmd" "$i}; printf "%10.2f MB %s\n", $6/1024, cmd}'
236.36 MB node -r dotenv-flow/config dist/server/app.js
288.86 MB Passenger RubyApp: /home/www-data/redmine1 (production)
379.55 MB Passenger RubyApp: /home/www-data/redmine2 (production)
543.54 MB /usr/sbin/mysqld
654.73 MB /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j2.formatMsgNoLookups=true -Djava.locale.providers=CLDR -Dorg.apache.lucene.vectorization.upperJavaFeatureVersion=24 -Des.distribution.type=deb -Des.java.type=bundled JDK --enable-native-access=org.elasticsearch.nativeaccess,org.apache.lucene.core --enable-native-access=ALL-UNNAMED --illegal-native-access=deny -XX:ReplayDataFile=/var/log/elasticsearch/replay_pid%p.log -Des.entitlements.enabled=true -XX:+EnableDynamicAgentLoading -Djdk.attach.allowAttachSelf=true --patch-module=java.base=lib/entitlement-bridge/elasticsearch-entitlement-bridge-8.19.2.jar --add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement,java.logging,java.net.http,java.naming,jdk.net -XX:+UseG1GC -Djava.io.tmpdir=/tmp/elasticsearch-10892987525338221374 --add-modules=jdk.incubator.vector -XX:+HeapDumpOnOutOfMemoryError -XX:+ExitOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:ErrorFile=/var/log/elasticsearch/hs_err_pid%p.log -Xlog:gc*,gc+age=trace,safepoint:file=/var/log/elasticsearch/gc.log:utctime,level,pid,tags:filecount=32,filesize=64m -Xms256m -Xmx256m -XX:MaxDirectMemorySize=134217728 -XX:G1HeapRegionSize=4m -XX:InitiatingHeapOccupancyPercent=30 -XX:G1ReservePercent=15 --module-path /usr/share/elasticsearch/lib --add-modules=jdk.net --add-modules=jdk.management.agent --add-modules=ALL-MODULE-PATH -m org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch
と、一番はElasticsearch(Growiで利用)。次いでMySQL、Redmineと続きます。nodeはGrowi関係です。
メモリ使用率(%MEM)を基準にして、MB単位で表示するワンライナー
続いて、システム全体のメモリ使用率を基準にする場合。
ps aux | tail -n +2 | sort -k 4 -rn | head -n 5 | sort -k 4 -n | awk '{cmd=""; for(i=11;i<=NF;i++){cmd=cmd" "$i}; printf "%5s%% %s\n", $4, cmd}'
ソートの基準をRSS(6列目)から %MEM(4列目) に変更している点が主な違いです。
4.3% node -r dotenv-flow/config dist/server/app.js
4.8% Passenger RubyApp: /home/www-data/redmine1 (production)
6.4% Passenger RubyApp: /home/www-data/redmine2 (production)
9.1% /usr/sbin/mysqld
11.0% /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j2.formatMsgNoLookups=true -Djava.locale.providers=CLDR -Dorg.apache.lucene.vectorization.upperJavaFeatureVersion=24 -Des.distribution.type=deb -Des.java.type=bundled JDK --enable-native-access=org.elasticsearch.nativeaccess,org.apache.lucene.core --enable-native-access=ALL-UNNAMED --illegal-native-access=deny -XX:ReplayDataFile=/var/log/elasticsearch/replay_pid%p.log -Des.entitlements.enabled=true -XX:+EnableDynamicAgentLoading -Djdk.attach.allowAttachSelf=true --patch-module=java.base=lib/entitlement-bridge/elasticsearch-entitlement-bridge-8.19.2.jar --add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement,java.logging,java.net.http,java.naming,jdk.net -XX:+UseG1GC -Djava.io.tmpdir=/tmp/elasticsearch-10892987525338221374 --add-modules=jdk.incubator.vector -XX:+HeapDumpOnOutOfMemoryError -XX:+ExitOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:ErrorFile=/var/log/elasticsearch/hs_err_pid%p.log -Xlog:gc*,gc+age=trace,safepoint:file=/var/log/elasticsearch/gc.log:utctime,level,pid,tags:filecount=32,filesize=64m -Xms256m -Xmx256m -XX:MaxDirectMemorySize=134217728 -XX:G1HeapRegionSize=4m -XX:InitiatingHeapOccupancyPercent=30 -XX:G1ReservePercent=15 --module-path /usr/share/elasticsearch/lib --add-modules=jdk.net --add-modules=jdk.management.agent --add-modules=ALL-MODULE-PATH -m org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch
と、実メモリ6GB中の11%をElasticsearchが占めていることが明らかになりました。
コメントを残す