현재 위치 - 중국 분류 정보 발표 플랫폼 - 비즈니스 서비스 정보 - LowMemoryKiller 메커니즘 분석

LowMemoryKiller 메커니즘 분석

Linux 시스템의 사용 가능한 메모리가 부족하면 oom 킬러 메커니즘은 특정 규칙에 따라 일부 프로세스를 종료하여 메모리를 해제하며 Android 시스템의 LowMemoryKiller 메커니즘은 이 기능을 기반으로 일부 조정을 수행했습니다. . Android 시스템의 APP는 사용 후 즉시 종료되지 않지만 다음에 여기에 애플리케이션을 입력할 때 프로세스 생성 프로세스를 저장하고 시작 속도를 높일 수 있습니다. LowMemoryKiller 메커니즘은 메모리 리소스가 부족할 때 메모리를 회수하기 위해 일부 프로세스를 종료합니다.

LowMemoryKiller 메커니즘은 세 부분으로 나뉩니다.

프레임워크의 ProcessList와 네이티브 lmkd 프로세스는 소켓을 통해 통신하는 반면, 커널의 lmkd와 LowMemoryKiller는 다음을 통해 파일 노드에 씁니다. writeFileString.Content 메소드가 통신합니다.

Framework 계층은 특정 규칙을 통해 프로세스의 adj 값과 메모리 공간 임계값을 조정한 다음 이를 소켓을 통해 lmkd 프로세스로 보냅니다. 하나는 lmkd를 작성하는 것입니다. 임계값을 파일 노드로 전송하여 커널의 LowMemoryKiller는 커널이 프로세스를 종료하는 데 사용됩니다. 다른 하나는 lmkd가 cgroup을 통해 메모리 사용량을 모니터링하고 자체적으로 종료할 프로세스를 계산한다는 것입니다.

lmkd는 init 프로세스에 의해 시작되는 기본 프로세스이며 /system/core/lmkd/lmkd.rc에 정의되어 있습니다.

lmkd.rc에서 lmkd 프로세스가 시작되고 소켓 프로세스 간 통신을 위해 lmkd라는 소켓 설명자를 만들었습니다. lmkd가 시작된 후 먼저 기본 메소드를 실행합니다.

main 메소드는 먼저 현재 프로세스의 스케줄링 규칙을 설정한 후 init 메소드와 mainLoop 메소드를 실행합니다.

lmkd의 init 메소드에서 수행된 작업

먼저 커널에 의해 구현된 LowMemoryKiller 프로세스 종료 메커니즘을 분석한 다음 lmkd에 의해 구현된 메커니즘을 분석합니다. 두 가지 모두의 최종 결과는 메모리가 부족할 때 메모리를 해제하기 위해 일부 프로세스를 종료하는 것이지만 구현 메커니즘은 다릅니다.

init 초기화가 완료된 후 mainloop 메소드를 입력하고 epoll 이벤트가 보고될 때까지 루프에서 기다립니다. epoll은 소켓 연결이 있을 때 ctrl_connect_handler를 모니터링합니다. 메소드가 호출됩니다.

소켓 연결을 들어보면 이때 lmkd에 연결된 소켓 클라이언트가 프레임워크라는 것을 알 수 있습니다. 연결이 오면 accept 메소드는 연결된 소켓FD를 반환하고 연결된 소켓FD도 추가됩니다. epoll에 읽을 수 있는 메시지가 있는 경우, 즉 프레임워크가 lmkd에 메시지를 보내면 epoll이 깨어나서 이를 처리하기 위해 ctrl_data_handler 메서드를 삭제합니다.

프레임워크와 lmkd 프로세스는 소켓을 통해 프로세스 간에 통신합니다. lmkd는 초기화되면 소켓 설명자 lmkd를 수신하여 프레임워크에서 보낸 메시지를 기다립니다.

프레임워크가 lmkd에 명령을 보내는 것과 관련된 세 가지 방법이 있습니다.

위의 세 가지 상황에서 프레임워크는 마침내 소켓을 통해 lmkd에 세 개의 메시지를 보냈습니다.

lmkd 명령 수신 처리 로직

lmkd는 epoll을 통해 소켓에 데이터가 있는지 모니터링합니다. 프레임워크에서 보낸 소켓 명령을 수락한 후 ctrl_cmmand_handler 메서드를 호출하여 표시하고 구문 분석합니다. 소켓의 명령과 매개변수, 명령에 따라 다른 메소드가 호출됩니다.

프로세스 종료를 구현하는 방법에는 두 가지가 있습니다. 하나는 축소기를 사용하여 낮은 메모리 재활용을 트리거하는 커널의 LMK입니다. 다른 하나는 cgroup을 통해 메모리 사용량을 모니터링하고 자체적으로 프로세스를 계산하고 종료하는 것입니다. 두 가지 구현은 동일하지 않으며 하나씩 분석해야 합니다.

메모리 임계값과 adj 값을 설정한다는 것은 프레임워크에서 받은 데이터를 문자열로 캡슐화하고 이를 커널 LMK에서 사용할 수 있도록 writefilestring을 통해 두 개의 파일 노드에 쓰는 것을 의미합니다.

/sys/module/lowmemorykiller/parameters/minfree: 메모리 수준 제한

/sys/module/lowmemorykiller/parameters/adj: 종료할 프로세스에 해당하는 메모리 수준 제한 adj

커널 LMK를 사용하므로 해당 프로세스의 oom_adj_score 파일에 우선순위를 직접 작성하여 프로세스 우선순위를 조정할 수 있습니다.

프로세스를 제거할 때 아무것도 할 필요가 없습니다.

Linux에는 kswapd라는 커널 스레드가 있습니다. Linux가 페이지를 회수하고 저장할 때 kswapd 스레드는 축소기를 통과합니다. 연결된 목록을 실행하고 콜백이 실행되거나, 앱이 시작되고 사용 가능한 메모리가 부족한 것으로 확인되면 커널은 메모리 할당을 요청한 프로세스의 메모리 할당 프로세스를 차단하고 해당 프로세스에서 lowmemorykiller를 실행하여 기억을 풀어보세요. 이전에 한 번도 노출된 적이 없지만 일반적으로 이 축소 콜백 함수를 시스템에 등록한 후 시스템에 여유 메모리 페이지가 부족할 때 이 콜백 함수가 호출된다는 것이 일반적인 이해입니다. 구조체 축소기의 정의는 linux/kernel/include/linux/shrinker.h에 있습니다.

커널 LowMemoryKiller 축소기의 등록 프로세스는 다음과 같습니다:

등록이 완료된 후 , 메모리가 부족하면 Shrinker가 다시 호출되며, 그 중 가장 중요한 것은 lowmem_scan 방법입니다. 구체적인 구현은 다음과 같습니다.

커널 LMK의 원리는 매우 간단합니다. 먼저 축소기를 등록하고, 메모리가 부족할 때 lowmem_scan 메소드가 트리거됩니다. 이 메소드가 수행하는 작업은 프로세스를 찾는 것입니다. , 그런 다음 그것을 죽이고 일부 메모리를 해제하십시오.

커널 LMK의 구현 로직이 분석되었습니다.

lmkd가 메모리 확인을 구현하는 방식은 cgroup 메모리를 기반으로 합니다.

cgroup 메모리란 무엇입니까?

Cgroup의 메모리 하위 시스템, 즉 memory cgroup(이하 이 문서에서는 memcg라고 함)은 프로세스 그룹의 메모리 동작 관리를 제공합니다. 이를 통해 전체 시스템에서 서로 다른 메모리 요구 사항을 갖는 프로세스나 애플리케이션을 차별화하고 관리하여 보다 효과적인 리소스 활용 및 격리를 달성합니다.

cgroup 메모리 관련 파일

cgroup의 원리를 간단히 이해한 후 lmkd의 init 메소드를 살펴보겠습니다.

먼저 메모리 Pressure_level의 사용법을 이해합니다< /p> p>

init_mp_common 메소드는 Pressure_level의 사용법을 엄격히 따르며 Pressure_level의 이벤트 콜백을 등록합니다. Pressure_level은 세 가지 레벨로 나뉩니다.

메모리가 해당 레벨에 도달하면 mp_event_common 메소드는 mp_event_common 메소드를 통해 다시 호출됩니다.

lmkd 메모리 검사 및 종료 원리:

프로세스 검사 및 종료의 두 가지 구현 방법은 모두 콜백을 등록합니다. 남은 메모리가 확인됩니다. 조정보다 큰 메모리를 종료합니다. 커널 축소 방법은 메모리가 부족할 때만 메모리를 해제하는 반면, cgroup 방법은 보다 정밀하게 제어할 수 있으며 다양한 수준에 따라 메모리 재활용을 트리거합니다.