먼저, 직접 메모리 수집을 실행할 수 있는 프로그램 작성 방법을 가르쳐 주는 데 도움을 요청하고 싶습니다.
아래와 같이 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로 설정됩니다. 스왑 파일이 비활성화되었습니다.
이 정보를 바탕으로 나는 다음과 같이 생각합니다.
- 일부 프로세스는 직접 재활용을 트리거했지만 일시중단되지는 않았습니다.
- 직접 재활용하면 다른 프로세스에 속하는 일부 페이지가 제거됩니다. (내가 아는 한, 직접 재활용은 발생한 경우에만 깨끗한 페이지를 제거합니다.)
- 프로세스 그룹이 페이지 오류를 트리거하여 과도한 시스템 로드를 유발하고 정지를 유발합니다.
내 가설을 검증하려면 직접 재활용을 재현해야 합니다.