
私のLinuxシステムがページングに近づくと(例えば、私の場合は16GBのメモリがいっぱいで、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)一部のメモリ/スワップテーブルの起動(例watch -n 1 free
:)
3)fasteater x y
xがギガバイト単位、yがメガバイト単位の複数のインスタンスを起動します。 RAMがほぼ満たされるまでこれを行います。
4) インスタンスが再起動されましたsloweater x y
。ここで、x は GB 単位、y は MB 単位です。
ステップ4以降に発生する必要がある作業(私のシステムでは常に発生します)は、メモリが不足するとシステムが完全にロックされることです。 GUIがロックされ、sshdがロックされています。しかし、永遠ではありません! Sloweaterが割り当て要求を完了すると、システムは次の動作で通常に戻ります(秒以外の時間ロックされた後...)。
a) メモリがほとんどいっぱいです。
b)スワップ領域もほとんどいっぱいです(最初は空であったことを覚えておいてください)。
c) oom Killer 介入はありません。
スワップパーティションはSSDにあります。したがって、システムは、遅い(わずか数メガバイトの)遅い要求のためのスペースを確保するために、ページをラムからスワップに徐々に移動できないように見えます(おそらくスリープ状態になった高速で)。
もし私が間違っているなら誰かが私を訂正することができますが、これは現代のシステムがこの状況で行動しなければならない方法ではないようです。ページングがサポートされておらず、仮想メモリシステムが数ページではなくプロセスのメモリスペース全体を交換した場合、既存のシステム(WAAAAAY)のように振る舞うようです。
誰かがこれをテストできますか?たぶん誰かがBSDシステムを持っているかもしれません。
アップデート1
私はそのアドバイスに従った。マーク・プロニック以下のコメントでは、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
ご覧のとおり、スワップが含まれるとすぐに15916880KBの大規模なスワップが発生します。これは明らかに、1秒あたり10 MBだけを要求するプロセス(遅い)によって引き起こされます。
アップデート2:私はすぐにFreeBSDをインストールし、Linuxと同じ配布方法を繰り返しました。すべてがうまくいった。 FreeBSDは徐々にページを交換しますが、速度の低下のために10MBのメモリブロックがすべて割り当てられます。質問もなく…ここで何が起こっているのでしょうか? !
アップデート3:提出しました抜け穴カーネルのバグトラッカーとして。興味を持っているようです...指が交差しています...
答え1
これが正しい衝撃保護に存在します。
スワップ状態を継続的に監視し、何かが予想外に多くのRAMを占有し始めると、RAMを大量に使用するプロセスが一時的に停止し、カーネルがシステム全体が応答しなくなることなく一部のメモリをスワップする時間があります。
答え2
メモリだけを割り当てるだけで、実際には何も入れません。 「一般」プログラムはブロックを割り当て、それを使用し始めます。割り当てはメモリ使用量とは異なります。