내 응용 프로그램은 여러 프로세스로 구성됩니다. 각 프로세스에는 여러 스레드가 있습니다.
힙 메모리 영역은 작업 중에 동적으로 할당되고 해제됩니다.
내 응용 프로그램에 메모리 누수 버그가 있었고 이를 수정했습니다. 그러다가 설날 연휴 동안 에이징 테스트를 실시했는데, 그 결과 버그가 완전히 수정되었음을 증명했습니다.
번인 테스트 중에는 또 다른 모니터링 프로세스가 주기적으로 애플리케이션 프로세스의 /proc/PID/statm을 읽어 그 값을 파일에 기록한다.
13일 후 메모리 로그 파일을 분석했습니다.
처음 10시간 정도 동안 상주 메모리(RES) 크기가 계속 증가합니다.
이는 glibc 라이브러리 메모리 할당자가 시스템에 "해제된 메모리"를 반환하지 않고 대신 향후 재사용을 위해 "아레나"에 메모리 조각을 유지하기 때문에 예상되는 동작입니다.
그런 다음 상주 메모리(RES) 크기가 상한에 도달하고 10일 동안 변경되지 않은 상태로 유지됩니다.
이는 메모리 누수 버그가 수정되었음을 의미합니다. 오랫동안 살다!
(수정 이전에는 한도에 도달하지 않고 계속 증가했습니다.)
놀랍게도 11일(약 270시간) 후에 상주 메모리의 크기는 가파른 각도(증가 기간보다 더 가파르게)로 감소하기 시작한 다음 "바닥"에 부딪혀 화상이 끝날 때까지 평평하게 유지되었습니다. - 기간 중.
대부분의 애플리케이션 프로세스는 동일한 동작을 보여줍니다(일부는 그렇지 않음).
270시간이 지나면 상주 메모리 크기가 줄어들기 시작합니다.
이러한 감소 이유를 설명할 수 있는 사람이 있습니까?
어떤 가설이라도 환영합니다.
"RES 크기 축소에 문제가 있나요?"라고 질문하실 수 있습니다.
감소 자체는 허용되지만 내 애플리케이션의 중요한 프로세스 및 스레드에 대해 타이밍 속도 저하 또는 일시적인 일시 중지를 유발하는 것 같습니다.
"내가 정말로 원하는 것"은 이러한 속도 저하나 일시적인 일시 중지의 원인을 제거하고 프로세스와 해당 스레드가 지연 없이 계속 실행되도록 하는 것입니다.
환경 정보:
운영 체제: Rocky Linux 버전 8.8(Green Obsidian) CPU: Intel(R) Core(TM) i7-9850HE CPU @ 2.70GHz 언어: C++17 gcc 버전(dnf 정보 gcc): 이름: 걸프 협력 협의회 버전: 8.5.0 출시: 18.el8 아키텍처: x86_64 크기: 59M 소스: gcc-8.5.0-18.el8.src.rpm glibc 버전(dnf 정보 glibc): 이름: glibc 버전: 2.28 버전: 225.el8 아키텍처: x86_64 크기: 6.4M 출처: glibc-2.28-225.el8.src.rpm
나는 두 가지 가설을 가지고 있습니다.
1.
다른 프로세스(애플리케이션 프로세스가 아님)에 상주 메모리가 할당되어 있고 시스템 전체의 총량이 최대치를 초과했습니다.
애플리케이션 프로세스는 더 이상 해제된 상주 메모리 영역을 유지할 수 없으며 "보관된 메모리 영역"을 시스템에 반환하기 시작합니다.
13일차에 "top" 명령의 결과를 확인한 결과 RES 크기가 크게 증가한 프로세스는 발견되지 않았습니다.
2.
Linux 또는 glibc 메모리 할당자에는 메모리 공간을 자동으로 자르기 위한 "하우스키핑" 메커니즘이 있습니다.
주기적으로 작동하며 프로세스가 해제된 메모리를 시스템에 반환하도록 강제합니다.
저도 온라인으로 정보를 확인했는데, 제가 찾은 내용은 다음과 비슷했고, 저의 '감소' 상황은 아니었습니다.
디버깅을 통해 힙 메모리 관리의 기본을 이해하지만(그래서 "아레나"가 무엇인지는 이해합니다) 자세한 내용은 모릅니다.