これはLinuxのページングの動作方法ですか?


26

Linuxシステムがページングに近づくと(つまり、私の場合、16GBのRAMがほぼいっぱいになり、16GBのスワップが完全に空になります)、新しいプロセス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番目の部分は、最初はそれが持っていることを除いてまったく同じものをしsleep(1);た後、右にprintf(私は全体のコードを繰り返すつもりはありません)。これは、システムがページングの瀬戸際にあるときに「穏やかな」方法でページをスワップアウトするために使用されます。つまり、新しいメモリチャンクの割り当てをゆっくりと要求します(システムが確実にページをスワップアウトできるように新しいリクエストに対応してください)。

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

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

2)mem / swapメーターを起動します(例watch -n 1 free

3)fasteater x yxがギガバイトのオーダーで、yがメガバイトのオーダーの複数のインスタンスを開始します。ラムがほぼいっぱいになるまでやります。

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

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

a)ラムがほぼ一杯です

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

c)殺人者の介入なし。

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

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

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

更新1 私はコメントで以下のMark Plotnickのアドバイスに従いvmstat 1 >out、ページングテストに進む前に始めました。以下の結果を見ることができます(スワップが関与することなくラムが満たされている最初の部分全体を切り取ります)。

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 Kバイトの大規模なスワップアウトが一度に発生します。これは、システムがフリーズする間ずっと続きます。そして、これらすべては明らかに毎秒10MBを要求するプロセス(遅い方)によって引き起こされます。

更新2: FreeBSDのクイックインストールを行い、Linuxで使用されているのと同じ割り当てスキームを繰り返しました...そして、それは本来のようにスムーズでした。FreeBSDはページを徐々に交換し、スローイーターは10MBのメモリチャンクをすべて割り当てました。どんな種類の問題もありません... WTFはここで起こっていますか?!

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


2
前述したように、すべてがロックされています。別のシステムからsshを試してみましたが、タイムアウトになりました。
ジョンテラゴン

2
vmstat 1をstdout出力で起動すると、フリーズすると思います。しかし、あなたは正しい、私vmstat 1>somefileはシステムから直接起動し、システムが生き返った後にそれが報告するものを見ることができます。やってみます。
ジョンテラゴン

2
vmstatを使用しました。上記の更新の結果。
ジョンテラゴン

3
swappinessデフォルトの60です(変更すると良い結果が得られるわけではありません)。vmstat実行で使用されたカーネルは4.14.35ですが、4.15、4.16を試し、4.0シリーズ(!)に戻りました:常に同じ動作です。そして、私が奇妙なディストリビューションを使用しているわけではなく、ただのdebianです。私はdebianのカーネルイメージを使用していません(私の場合は異常な構成ではありません)が、そのうちの1つを試してみました...同じ動作です。
ジョンテラゴン

2
カーネルのバグに関する非常に興味深い議論!そして、LUKSで暗号化されたパーティションをスワップするためにこの問題を分離したようです。答えを編集したり、自分で答えを投稿したりすることもできます(これまでにわかっている回避策を使用し、LKMLの議論がより決定的な結果に達すると、更新し続けるかもしれません)。😁
filbranden

回答:


1

これはまさに、thrash-protectが存在するものです。

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


-3

メモリを割り当てるだけです-実際には何も入れません。「通常の」プログラムは、チャンクを割り当ててから使用を開始します。割り当てはメモリ使用量と同じではありません。


3
Unix StackExchangeへの投稿へようこそ。データを入れますが、そのデータはたまたまゼロです。memset()を参照してください。Linuxカーネルは、仮想ページに書き込むとすぐにRAMの物理ページを提供します。書き込まれた特定の値は参照しません。
sourcejedi

実際、私はこれをコンパイルして、デスクトップで2GBの使用、6GBの空き容量で実行しました。最初は実際には低速でスワップアウトされ、制限に達した場合にのみ積極的にスワップアウトされました。これにより、さまざまなGUIアクションが捕捉されました。
ジェレミーボーデン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.