まず、直接メモリー収集を実行できるプログラムの作成方法を教えてくれるように助けを求めたいと思います。
以下のように、mmapを使用してメモリを割り当てるプログラムを作成しました。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#define PAGE_SZ 4096
#define GB (1<<30)
int random_number(int min, int max) {
return min + rand() % (max - min + 1);
}
int main(int argc, char** argv) {
size_t size;
size = 5ul * GB;
printf("size %lu\n",size);
void *mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
size_t num_pages = size / PAGE_SZ;
size_t i;
for (i = 0; i < num_pages; i++) {
*((char *)mem + i * PAGE_SZ) = '6';
}
srand(time(NULL));
while (1) {
size_t random_page = random_number(0, num_pages - 1);
char first_byte = *((char *)mem + random_page * PAGE_SZ);
}
return 0;
}
しかし、利用可能なフィールドのみが減少したが、フリーフィールドは大きな減少を示さないことが確認された。このため、直接メモリ収集をトリガすることは困難です。
それでは、空きフィールドと利用可能なフィールドを同時に減らす方法を知りたいです。
直接メモリ回収を効果的に実行できるテストプログラムを作成する方法に関する提案やアドバイスをいただきありがとうございます。
私がこのテストをやりたかった理由は次のとおりです。
最近、私のサーバーで数秒から10分まで続くいくつかの中断が発生しました。
「D」状態のプロセスの呼び出し追跡とメモリ状態を監視するプログラムを導入しました。
まず、私が行方不明中に発見した内容を説明します。
- 同様の呼び出しトレースを持つ「D」状態のプロセスがたくさんあります:page_fault->...->filmap_fault()->__lock_page_or_retry()->io_schedule()。 __alloc_page_slowpathに停止したプロセスはありません。
- システムは、2秒ごとに/ proc / vmstatのpgsteal_direct変更のロギングを監視して、直接メモリーの回復をトリガーします。変化の規模は数千万、さらには数百万に達することができます。
- 「free -h」の空き容量と空き容量は、ダイレクトリサイクルが発生する前と後にそれぞれ15GBと2GBです。
以下は、サーバーに関するいくつかの情報です。サーバーには128GBのメモリがあります。 /proc/sys/vm/min_free_kbytesの値は2GBに設定されます。スワップファイルが無効になっています。
この情報に基づいて、私は次のように思います。
- 一部のプロセスは直接リサイクルをトリガーしましたが、中断されませんでした。
- 直接リサイクルすると、他のプロセスに属する一部のページが削除されます。 (私が知っている限り、直接リサイクルは発生した場合にのみクリーンなページを削除します。)
- プロセスグループはページエラーを引き起こし、過度のシステム負荷を引き起こし、停止を引き起こします。
私の仮説を検証するには、直接リサイクルを再現する必要があります。