`ru_maxrss`が予想よりも多くの使用量を返す理由

`ru_maxrss`が予想よりも多くの使用量を返す理由

プログラムランチャーをテストしています。 GNU Time 1.9を使用して以下のコードをテストするとき

// nul.c
#include <stdio.h>
#include <sys/resource.h>

int main()
{
  struct rusage r_usage;
  getrusage(RUSAGE_SELF, &r_usage);
  printf("%ld\n", sizeof r_usage);
  printf("%ld\n", r_usage.ru_maxrss);
  return 0;
}

コンパイル用

gcc nul.c -o nul

そして走る

/usr/bin/time -v ./nul

、報告

144
576
    Command being timed: "./nul"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 1424
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 61
    Voluntary context switches: 1
    Involuntary context switches: 4
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

最大常駐セット・サイズがプログラムの出力を満たさない。さらなるテストの後、maxrssGNU時間に報告されたサイズは常に約1400kBです。そして以下のコードをテストしてください

// nul2.c
int main(){ return 0; }

コンパイル用

gcc nul2.c -o nul2

そして走る

/usr/bin/time -v ./nul2

GNU時間は〜1000kBのmaxrss使用量を報告します。しかし、私のプログラムではメモリ空間は使用されません。それでは、maxrssなぜ使用量が〜0kBでないのですか?プログラムで使用されている物理メモリを測定する方法は何ですか?


修正する:

私は空のアセンブリプログラムを書いた。

.text
.global _start
_start:
    movl $0, %ebx
    movl $1, %eax
    int  $0x80

次にコンパイル

as -o nul.o nul.s
ld -s -o nul nul.o

GNU時間でテストしました。

    Command being timed: "./nul"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 61%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 128
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 13
    Voluntary context switches: 1
    Involuntary context switches: 0
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

また、最大RSS使用量は128kBです。どこから来たの?

答え1

あなたの電話番号はここの私の電話番号に似ています。

あなたのプログラムがライブラリを使用していることを忘れないでください。 (たとえば、関数はprintfプログラムの一部です。関数のバッファは、プログラムの開始時、その後、またはその両方に割り当てられます。コードがメモリにロードされると、コードもRSSとして計算されます。)数量が0で、プロセスが完了する前に数量が増加するという事実。

(コマンドやデバッガを読み込んで)プロセスの実行を中止する場合は、/proc/<pid>/...遅いプログラムなどを使用してlsofそのメモリを調べることができます。

特に、プログラムは/usr/lib/x86_64-linux-gnu/libc.so.6ハードドライブで2.2 MB(または同様)を使用しています(すべての項目をロードする必要はありません)。


たぶんそれはすべてです。

/usr/bin/time -v ./nul2 "$(seq -w 1 16000)"

コマンドラインもプロセスメモリの一部になるため、報告された数字は少し高くなります。



修正する:

今、あなたはより低いレベルに移動しました。おめでとうございます。 Cコンパイラの使用可能性と標準ライブラリを含まないオプションをスキップしました。 (ランダム協会おそらく方向が間違っているようです。 )

私はあなたがすでにいくつかの答えを知っていると思いますWhy(それはあなたが質問した方法です)(したがって、この質問はすでに答えられており、おそらくより良いかもしれませんし、より悪いかもしれません)。そしておそらくxxxよりも「より少ないプログラムをコンパイルする方法」のような新しい質問をしたいかもしれません。この/または/それのメモリ"。 動機を説明する必要があるようです。 最小限のインストールスペースでプロセスを実行したいですか?しますか?

gdbあなたのアセンブラの場合(break _startおよび使用)で実行して見ることrができます。

cat  /proc/222226/maps     # the number is PID of the process
00400000-00401000 r--p 00000000 103:04 1049144                           /home/h/tmpdir/asm.tmp.1
00401000-00402000 r-xp 00001000 103:04 1049144                           /home/h/tmpdir/asm.tmp.1
7ffff7ff9000-7ffff7ffd000 r--p 00000000 00:00 0                          [vvar]
7ffff7ffd000-7ffff7fff000 r-xp 00000000 00:00 0                          [vdso]
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

そして

cat  /proc/222226/maps | tr a-z A-Z | awk 'BEGIN {print "ibase=16";}; {print $1}; ' | bc -l
-4096
-4096
-16384
-8192
-135168
-4096

しかし、それがRSSやその他などにどれだけ貢献しているかはわかりません。周りを見回すと、/proc/222226/smapsRSSはあまり見えませんでした。

注:コマンドラインの内容がメモリを占有しているとすでに言及しています。環境も同じだ。

実際に報告された内容は何ですか/usr/bin/timeプログラムはどのように始まりますか? (明示的にまたはライブラリの組み合わせから隠されている)を介して起動すると、fork独自のメモリ使用量が使用されているメモリに影響を与えます。次の内容が面白そうです。

$  /usr/bin/time -v nonexisting
/usr/bin/time: cannot run nonexisting: No such file or directory
Command exited with non-zero status 127
    Command being timed: "nonexisting"
...
    Maximum resident set size (kbytes): 768
    Minor (reclaiming a frame) page faults: 40

したがって、エラー(またはその他)から回復するtimeために、ほとんどの新しいメモリを使用してメッセージを印刷し、そのジョブで40ページのエラーが発生します。 (おそらくその巨大なお金の大部分は、予期せぬクリーンアップとフォークされたプロセスを終了するのは難しい作業に費やされましたが、とにかくそうです。)execcannot run...

How要約:代わりに新しい質問を始めることをお勧めしますWhy

関連情報