psとfreeで表示される結果の一部について少し混乱しています。
私のサーバーでは、これはfree -m
の結果です
[root@server ~]# free -m
total used free shared buffers cached
Mem: 2048 2033 14 0 73 1398
-/+ buffers/cache: 561 1486
Swap: 2047 11 2036
Linuxがメモリを管理する方法についての私の理解は、ディスクの使用量をRAMに保存するため、その後の各アクセスがより速くなるということです。これは「キャッシュされた」列で示されていると思います。さらに、「バッファ」列に示されているさまざまなバッファがRAMに格納されます。
したがって、私が正しく理解していれば、「実際の」使用量は「-/ +バッファ/キャッシュ」の「使用済み」値、またはこの場合は561であると考えられます。
したがって、これらすべてが正しいと仮定すると、私をスローするのはps aux
の結果です。
ps
の結果についての私の理解は、6番目の列(RSS)がプロセスがメモリに使用するキロバイト単位のサイズを表すということです。
したがって、このコマンドを実行すると:
[root@server ~]# ps aux | awk '{sum+=$6} END {print sum / 1024}'
1475.52
結果はfree -m
の「-/ + buffers/cache」の「used」列ではないのですか?
では、Linuxのプロセスのメモリ使用量を適切に判断するにはどうすればよいですか?どうやら私の論理には欠陥があります。
これexact同じ質問が serverfault 先日行われた:-)
Linuxの仮想メモリシステムはそれほど単純ではありません。すべてのRSSフィールドを合計して、used
によって報告された値をfree
で取得することはできません。これには多くの理由がありますが、最大の原因をいくつか挙げます。
プロセスがフォークすると、親と子の両方が同じRSSで表示されます。ただし、Linuxはcopy-on-write
両方のプロセスが実際に同じメモリを使用するようにします。プロセスの1つがメモリを変更したときにのみ、実際にメモリが複製されます。したがって、これによりfree
の数値はtop
RSSの合計よりも小さくなります。
RSS値には共有メモリは含まれません。共有メモリは1つのプロセスによって所有されていないため、top
はRSSにそれを含めません。したがって、これにより、free
の数値がtop
RSSの合計よりも大きくなります。
合計するメモリ番号を探している場合は、 smem を参照してください。
smemは、Linuxシステムでのメモリ使用量に関する多数のレポートを提供できるツールです。既存のツールとは異なり、smemはプロポーショナルセットサイズ(PSS)を報告できます。PSSは、仮想メモリシステム内のライブラリとアプリケーションによって使用されるメモリの量のより意味のある表現です。
物理メモリの大部分は通常複数のアプリケーション間で共有されるため、常駐セットサイズ(RSS)と呼ばれるメモリ使用量の標準的な測定値は、メモリ使用量を大幅に過大評価します。代わりに、PSSは各共有領域の各アプリケーションの「フェアシェア」を測定して、現実的な測定を行います。
例えばここに:
# smem -t
PID User Command Swap USS PSS RSS
...
10593 root /usr/lib/chromium-browser/c 0 22868 26439 49364
11500 root /usr/lib/chromium-browser/c 0 22612 26486 49732
10474 browser /usr/lib/chromium-browser/c 0 39232 43806 61560
7777 user /usr/lib/Thunderbird/thunde 0 89652 91118 102756
-------------------------------------------------------------------------------
118 4 40364 594228 653873 1153092
PSS
は、共有メモリを考慮しているため、ここでは興味深い列です。RSS
とは異なり、合計することには意味があります。ここでは、ユーザーランドプロセスの合計が654Mbになります。
システム全体の出力は、残りについて説明します。
# smem -tw
Area Used Cache Noncache
firmware/hardware 0 0 0
kernel image 0 0 0
kernel dynamic memory 345784 297092 48692
userspace memory 654056 181076 472980
free memory 15828 15828 0
----------------------------------------------------------
1015668 493996 521672
つまり、1 Gb RAM合計 = 654Mb ユーザーランドプロセス + 346Mb カーネルメモリ + 16Mb 自由
(与えるか、数Mbを取る)
全体でメモリの約半分がキャッシュに使用されます(494Mb)。
ボーナス質問:ユーザーランドキャッシュとカーネルキャッシュの違いは何ですか?
何か視覚的な試みのために:
# smem --pie=name
本当に良いツールはpmap
で、特定のプロセスの現在のメモリ使用量を一覧表示します。
pmap -d PID
詳細については、man pmap
のマンページを参照してください。また、Linuxに関する情報を取得するために常に使用する優れたツールの一覧である すべてのSysAdminが知っておくべき20のLinuxシステム監視ツール もご覧ください。ボックス。
Topを実行し、h
を押してヘルプを表示し、次にf
を押してフィールドを追加します。次のフィールドを追加できます。
RSS
アプリケーションが使用している物理メモリの量CODE
プロセスの実行可能コードが使用しているメモリの総量DATA
-プロセスのデータとスタック専用のメモリの総量(kb)これら3つの間では、かなり正確な結果が得られるはずです。 htop
またはatop
をお勧めします。
編集:本当に詳細な情報が必要な場合は、ほとんど忘れてしまいました。 PIDを見つけて、次のファイルをcatします。
PID=123
cat /proc/123/status
編集2:あなたがそれを見つけるか、それを本に持っている場合:
Linuxパフォーマンスの最適化:Linuxパフォーマンスツールの実践ガイド
-セクション第5章:パフォーマンスツール:プロセス固有のメモリ-セクションがあります。これには、必要以上に多くの情報があります。
ps
は、各プロセスで使用されるメモリの量を示します。そのメモリの一部はキャッシュ内でカウントされるmmappedファイルです。そのメモリの一部(特にコード)は他のプロセスと共有されるため、RSS値を合計すると、複数回カウントされます。
「このプロセスが使用するメモリの量」に対する正しい答えはありません。これは、プロセスだけに依存するのではなく、環境にも依存するためです。プロセスの「メモリ使用量」と呼ばれる可能性のあるさまざまな値があり、それらは異なるものをカウントしているため、一致または合計されません。
他の人が正しく指摘しているように、プロセスによって使用される実際のメモリ、共有領域で何が行われるか、mmapされたファイルなどでハンドルを取得することは困難です。
実験者であれば、 valgrind and massif を実行できます。これは、カジュアルなユーザーにとっては少し重くなるかもしれませんが、アプリケーションのメモリの動作について、時間の経過とともにわかります。アプリケーションmalloc()がまさにそれを必要とする場合、これはプロセスの実際の動的メモリ使用量を適切に表現します。しかし、この実験は「毒殺」される可能性があります。
問題を複雑にするために、Linuxでは overcommit メモリーを使用できます。メモリをmalloc()するときは、メモリを消費する意図を示しています。しかし、割り当てられた「RAM」の新しいページにバイトを書き込むまで、割り当ては実際には起こりません。次のような小さなCプログラムを作成して実行することで、これを自分で証明できます。
// test.c
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
int main() {
void *p;
sleep(5)
p = malloc(16ULL*1024*1024*1024);
printf("p = %p\n", p);
sleep(30);
return 0;
}
# Shell:
cc test.c -o test && ./test &
top -p $!
RAM= 16GB未満のマシンでこれを実行すると、16GBのメモリを獲得したことになります!.
top
には「VIRT」が16.004Gと表示されていますが、%MEMは0.0です。
Valgrindでこれをもう一度実行します。
# Shell:
valgrind --tool=massif ./test &
sleep 36
ms_print massif.out.$! | head -n 30
そしてMassifは「すべてのallocs()の合計= 16GB」と言います。だからそれはあまり面白くない。
しかし、saneプロセスで実行した場合:
# Shell:
rm test test.o
valgrind --tool=massif cc test.c -o test &
sleep 3
ms_print massif.out.$! | head -n 30
--------------------------------------------------------------------------------
Command: cc test.c -o test
Massif arguments: (none)
ms_print arguments: massif.out.23988
--------------------------------------------------------------------------------
KB
77.33^ :
| #:
| :@::@:#:
| :::::@@::@:#:
| @:: :::@@::@:#:
| ::::@:: :::@@::@:#:
| ::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| :@@@@@@@@@@@@@@@@@@@@:@::@:::@:::::@:: :::@@::@:#:
| :@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
0 +----------------------------------------------------------------------->Mi
0 1.140
そしてここでは、コンパイラが77KBのヒープを割り当てたことが(非常に経験的に、非常に高い信頼度で)わかります。
なぜヒープ使用量だけを取得するために一生懸命に努力するのですかプロセスが使用するすべての共有オブジェクトとテキストセクション(この例ではコンパイラ)はそれほど興味深いものではないためです。それらはプロセスの一定のオーバーヘッドです。実際、その後のプロセスの呼び出しは、ほぼ「無料」で行われます。
また、以下を比較対照してください。
MMAP()1GBファイル。 VMSizeは1 + GBになります。しかし、常駐セットのサイズは、(その領域へのポインタを逆参照することによって)ページインされたファイルの部分のみになります。そして、ファイル全体を「読み取った」場合、最後までたどり着くまでに、カーネルは最初のページをすでにページアウトしている可能性があります(カーネルが再び逆参照された場合にこれらのページを置き換える方法/場所を正確に知っているため、これは簡単に実行できます) )。どちらの場合も、VMSizeもRSSも、メモリの「使用状況」を示す適切な指標ではありません。実際にはmalloc()を実行していません。
対照的に、メモリがディスクにスワップされるまで、Malloc()とメモリの多くに触れます。したがって、割り当てられたメモリはRSSを超えています。ここで、VMSizeが何かを伝え始める可能性があります(プロセスは、RAMに実際に存在するものよりも多くのメモリを所有しています)。しかし、共有ページであるVMと、スワップされたデータであるVMを区別することは依然として困難です。
これは、valgrind/massifが面白くなるところです。 意図的に割り当てたものを表示します(ページの状態に関係なく)。
これを試してください:MBで実行されているすべてのプロセスによって実際に使用されている合計RAM
ps -eo size,pid,user,command --sort -size | awk '
{ hr=$1/1024 ; printf("%13.2f Mb ",hr) }
{ for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }
' | awk '{total=total + $1} END {print total}'