web-dev-qa-db-ja.com

これはLinuxのページングの振る舞いですか?

Linuxシステムがページングに近づくと(つまり、私の場合、16 GBのRAMがほぼいっぱいになり、16 GBのスワップが完全に空になり)、新しいプロセスXがメモリを割り当てようとすると、システムは完全にロックします。つまり、不均衡な量のページ(Xのメモリ割り当て要求の合計サイズとレートを書き込む)がスワップアウトされるまでです。 GUIが完全に応答しなくなるだけでなく、sshdなどの基本的なサービスも完全にブロックされることに注意してください。

これらは、私がこの動作をより「科学的な」方法でトリガーするために使用する2つのコード(確かに粗雑)です。最初のコマンドは、コマンドラインから2つの数値x、yを取得し、合計xを超えるバイトが割り当てられるまで、yバイトの複数のチャンクの割り当てと初期化に進みます。そして、いつまでも眠り続けます。これは、システムをページングの瀬戸際に置くために使用されます。

_#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv) {
   long int max = -1;
   int mb = 0;
   long int size = 0;
   long int total = 0;
   char* buffer;

   if(argc > 1)
     {
       max = atol(argv[1]);
       size = atol(argv[2]);
     }
   printf("Max: %lu bytes\n", max);
   while((buffer=malloc(size)) != NULL && total < max) {
       memset(buffer, 0, size);
       mb++;
       total=mb*size;
       printf("Allocated %lu bytes\n", total);       
   }      
   sleep(3000000);
   return 0;
}
_

2番目のコードは、printfの直後にsleep(1);があることを除いて、最初のコードとまったく同じです(コード全体を繰り返すことはしません)。これは、システムがページングの瀬戸際にあり、「穏やかな」方法でページをスワップアウトするときに使用されます。つまり、システムが確実にページをスワップアウトできるように、新しいメモリのチャンクの割り当てをゆっくりと要求します。新しいリクエストに対応します)。

したがって、2つのコードをコンパイルしたら、それぞれのexeをfasteaterとsloweaterと呼びましょう。これを実行しましょう。

1)お気に入りのGUIを開始します(もちろん厳密には必要ありません)

2)mem/swapメーターを開始します(例:_watch -n 1 free_)

3)_fasteater x y_の複数のインスタンスを開始します。ここで、xはギガバイトのオーダーであり、yはメガバイトのオーダーです。ラムがほぼ満杯になるまで続けます。

4)_sloweater x y_の1つのインスタンスを開始します。ここでも、xはギガバイトのオーダーであり、yはメガバイトのオーダーです。

ステップ4)の後、起こるべきこと(そして、私のシステムでは常に起こります)は、RAMを使い果たした直後に、システムが完全にロックすることです。 guiはロックされています。sshdはロックされています。 sloweaterが割り当て要求を完了した後、システムは次の状況で(数秒ではなく数分のロック後...)元の状態に戻ります。

a)ramはほぼ満杯です

b)スワップもほぼ満杯です(最初は空でした)

c)oom killer介入なし。

スワップパーティションがSSD上にあることに注意してください。したがって、システムは、ページをramからswapに(おそらく、スリープ状態にあるfasteaterから)徐々に移動して、sloweaterの遅い(そして数メガバイトの)リクエストのためのスペースを作ることができないようです。

さて、私が間違っていれば誰かが私を訂正しますが、これは現代のシステムがこの設定で動作する方法とは思えません。ページングのサポートがなく、仮想メモリシステムがいくつかのページではなく、いくつかのプロセスのメモリスペース全体をスワップアウトしたとき、古いシステムのように動作するように見えます(戻る)。

誰かもこれをテストできますか?そして、おそらくBSDシステムも持っている誰か。

UPDATE 1以下のコメントで Mark Plotnick からのアドバイスに従い、続行する前に_vmstat 1 >out_を開始しましたページングテスト。以下の結果を見ることができます(私はramがスワップの関与なしで満たされる最初の部分全体をカットしました):

_procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
0  0   6144 160792      8 272868    0    0     0     0  281 1839  1  0 99  0  0
0  0   6144 177844      8 246096    0    0     0     0  425 2300  1  1 99  0  0
0  0   6144 168528      8 246112    0    0    16     0  293 1939  1  0 99  0  0
0  0   6144 158320      8 246116    0    0     0     0  261 1245  0  0 100  0  0
2  0  10752 161624      8 229024    0 4820 17148  4820  845 3656  1  2 97  0  0
2  0  10752 157300      8 228096    0    0 88348     0 2114 8902  0  5 94  1  0
0  0  10752 176108      8 200052    0    0 108312     0 2466 9772  1  5 91  3  0
0  0  10752 170040      8 196780    0    0 17380     0  507 1895  0  1 99  0  0
0 10  10752 160436      8 191244    0    0 346872    20 4184 17274  1  9 64 26  0
0 29 12033856 152888      8 116696 5992 15916880 1074132 15925816 819374 2473643  0 94  0  6  0
3 21 12031552 295644      8 136536 1188    0 11348     0 1362 3913  0  1 10 89  0
0 11 12030528 394072      8 151000 2016    0 17304     0  907 2867  0  1 13 86  0
0 11 12030016 485252      8 158528  708    0  7472     0  566 1680  0  1 23 77  0
0 11 12029248 605820      8 159608  900    0  2024     0  371 1289  0  0 31 69  0
0 11 12028992 725344      8 160472 1076    0  1204     0  387 1381  0  1 33 66  0
0 12 12028480 842276      8 162056  724    0  3112     0  357 1142  0  1 38 61  0
0 13 12027968 937828      8 162652  776    0  1312     0  363 1191  0  1 31 68  0
0  9 12027456 1085672      8 163260  656    0  1520     0  439 1497  0  0 30 69  0
0 10 12027200 1207624      8 163684  728    0   992     0  411 1268  0  0 42 58  0
0  9 12026688 1331492      8 164740  600    0  1732     0  392 1203  0  0 36 64  0
0  9 12026432 1458312      8 166020  628    0  1644     0  366 1176  0  0 33 66  0
_

ご覧のとおり、スワップが発生するとすぐに、15916880キロバイトの大規模なスワップアウトが一度に発生します。これは、システムがフリーズしている間ずっと続くと思います。そして、これはすべて、毎秒10MBを要求するプロセス(遅い)が原因であるようです。

UPDATE 2:FreeBSDのクイックインストールを行い、Linuxで使用されているのと同じ割り当て方式を繰り返しました...そしてそれは本来あるべきようにスムーズでした。 FreeBSDはページを徐々にスワップしましたが、低速のユーザーは10MBのメモリチャンクをすべて割り当てました。なんの問題もありません... WTFはここで起こっていますか?!

更新3:カーネルバグトラッカーに バグ を提出しました。注目されているようです...指が交差しました...

26
John Terragon

これがまさに thrash-protect が存在する理由です。

それは常にスワッピング状態を監視し、何かが誤って大量のRAMを占有し始めると、一時的にRAM貪欲なプロセスをフリーズさせるので、カーネルはシステム全体を無応答にすることなく、一部のメモリをスワップアウトする時間があります。

1
bodqhrohro