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 y
xがギガバイトのオーダーで、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はここで起こっていますか?!
vmstat 1>somefile
はシステムから直接起動し、システムが生き返った後にそれが報告するものを見ることができます。やってみます。
swappiness
デフォルトの60です(変更すると良い結果が得られるわけではありません)。vmstat
実行で使用されたカーネルは4.14.35ですが、4.15、4.16を試し、4.0シリーズ(!)に戻りました:常に同じ動作です。そして、私が奇妙なディストリビューションを使用しているわけではなく、ただのdebianです。私はdebianのカーネルイメージを使用していません(私の場合は異常な構成ではありません)が、そのうちの1つを試してみました...同じ動作です。