6

Linuxでのメモリマッピングとメモリ消費量の増加に関して、複数のスレッドで説明されている問題があります。

LinuxまたはMacOSXで1GBのファイルを開き、を使用してメモリにマップすると

me.data_begin = mmap(NULL, capacity(me), prot, MAP_SHARED, me.file.handle, 0);

マップされたメモリを順番に読み取ると、posix_madviseを使用しましたが(読み取りプロセス中に何度も呼び出された場合でも)、プログラムはますます多くの物理メモリを使用します。

posix_madvise(me.data_begin, capacity(me), MMAP_SEQUENTIAL);

成功せずに。:-(

私は試した:

  • 異なるフラグMMAP_RANDOM、MMAP_DONTNEED、MMAP_NORMALが成功しなかった
  • mmapを呼び出す前後のposix_fadvise(me.file.handle、0、capacity(me)、POSIX_FADV_DONTNEED)->成功しません

MacOSXで動作します!!! 組み合わせると

posix_madvise(.. MMAP_SEQUENTIAL)

msync(me.data_begin, capacity(me), MS_INVALIDATE).

常駐メモリが16M未満です(16mioステップ後に定期的にmsyncを呼び出しました)。

しかし、Linuxでは何も機能しません。Linuxでの私の問題について、誰かがアイデアやサクセスストーリーを持っていますか?

乾杯、デビッド

4

1 に答える 1

11

Linux のメモリ管理は、他のシステムとは異なります。重要な原則は、使用されていないメモリは浪費されているメモリであるということです。多くの方法で、Linux はメモリ使用量を最大化しようとし、(ほとんどの場合) パフォーマンスが向上します。

Linux で「何も動かない」ということではなく、Linux の動作が予想と少し違うということです。

メモリー・ページが mmap ファイルから取り出されるとき、オペレーティング・システムは、使用するためにどの物理メモリー・ページを解放 (またはスワップ・アウト) するかを決定する必要があります。スワップアウトしやすく (すぐにディスクに書き込む必要がない)、再度使用される可能性が低いページを探します。

madvice() POSIX 呼び出しは、アプリケーションがどのようにページを使用するかをシステムに伝える役割を果たします。しかし、名前が示すように、これはオペレーティング システムがページングとスワッピングの決定をより適切に行えるようにするためのアドバイスです。方針でも命令でもない。

Linux での madvice() の効果を実証するために、学生に与えた演習の 1 つを変更しました。ここで完全なソース コードを参照してください。私のシステムは 64 ビットで、2 GB の RAM があり、現在約 50% が使用されています。プログラムを使用して 2 GB のファイルを mmap し、順番に読み取り、すべてを破棄します。200 MB の読み取りごとに RSS の使用状況が報告されます。maadvice() を使用しない場合の結果:

<juliano@home> ~% ./madvtest file.dat n
     0 :     3 MB
   200 :   202 MB
   400 :   402 MB
   600 :   602 MB
   800 :   802 MB
  1000 :  1002 MB
  1200 :  1066 MB
  1400 :  1068 MB
  1600 :  1078 MB
  1800 :  1113 MB
  2000 :  1113 MB

Linux は、約 1 GB が読み取られるまで、メモリから何かをプッシュし続けました。その後、プロセス自体に圧力をかけ始め (残りの 50% のメモリが他のプロセスによってアクティブになったため)、ファイルの最後まで安定しました。

今、maadvice() で

<juliano@home> ~% ./madvtest file.dat y
     0 :     3 MB
   200 :   202 MB
   400 :   402 MB
   600 :   494 MB
   800 :   501 MB
  1000 :   518 MB
  1200 :   530 MB
  1400 :   530 MB
  1600 :   530 MB
  1800 :   595 MB
  2000 :   788 MB

Linux は、madvice() を使用しない場合よりもはるかに早く、約 500 MB に達するまでプロセスにページを割り当てることにしたことに注意してください。これは、その後、現在メモリ内にあるページが、このプロセスによって順次アクセスとしてマークされたページよりもはるかに価値があるように見えたためです。VMM には、プロセスから古いページのドロップをいつ開始するかを定義するしきい値があります。

Linux が 500 MB 程度までページを割り当て続け、シーケンシャル アクセスとしてマークされていたのに、すぐに停止しなかった理由を疑問に思うかもしれません。とにかくシステムに十分な空きメモリ ページがあったか、他の常駐ページが古すぎて保持できなかったことが原因です。もう役に立たないように思われる古代のページをメモリに保持することと、現在実行中のプログラムに提供するページを増やすことの間で、Linux は 2 番目のオプションを選択します。

シーケンシャル アクセスとマークされていたとしても、それは単なるアドバイスにすぎません。アプリケーションは、これらのページに戻って再度読み取る必要がある場合があります。または、システム内の別のアプリケーション。madvice() 呼び出しは、アプリケーション自体が何をしているかのみを示します。Linux は全体像を考慮します。

于 2010-09-24T20:04:02.303 に答える