Android 17 이상에서는 프로세스별로 메모리 사용량을 사전 예방적으로 관리하여 시스템 상태와 사용자 환경을 보호하는 프로세스 메모리 가디언 데몬 (PMGD)을 지원합니다. 이 데몬은 특정 타겟 프로세스에서 메모리 상한을 적절하게 적용하여 전반적인 기기 안정성을 개선하고 격리된 메모리 누수나 급증이 시스템 전체 성능 저하를 일으키지 않는지 확인합니다.
기존의 전역 메모리 부족 킬러는 전체 시스템에 압력이 가해질 때만 작동하지만 PMGD는 세부적인 접근 방식을 취합니다. 데몬은 타겟 프로세스의 Control Group v2 메모리 값을 모니터링하여 이를 달성합니다.
타겟팅된 프로세스가 구성된 메모리 한도를 초과하면 pmgd는 프로세스를 종료하기 전에 Statsd 메모리 원자를 로깅하여 한도 위반을 처리합니다.
작동 방식
데몬은 inotify를 사용하여 메모리 압력 이벤트 (특히 memory.events을 사용하는 고메모리 활동)를 수신 대기합니다. 모니터링된 프로세스가 메모리 이벤트를 트리거하면 pmgd는 다음 작업을 실행합니다.
- 익명 메모리 확인: 프로세스의 익명 메모리를 평가합니다. 구성된
anon_limit_in_mb를 초과하면pmgd가 프로세스를 즉시 종료합니다. - 회수 대기 기간: 익명 메모리가 지정된 익명 메모리 한도 미만이면
pmgd는 시스템 회수 유예 기간 (reclaim_wait_time_secs)을 기다립니다. - 회수 후 메모리 평가: 유예 기간이 지난 후에도 타겟 프로세스의
memory.current가memory.high이상으로 유지되거나 또는 익명 메모리가anon_limit_in_mb를 초과하면pmgd가 즉시 프로세스를 종료합니다.
이 작업은 프로세스가 종료되거나 프로세스에서 회수가 지정된 메모리 한도 아래로 메모리 사용량을 낮출 때까지 계속됩니다.
시스템 상태 기능
- 재부팅 비율 제한: 부팅 루프나 지속적인 비정상 종료를 방지하기 위해
pmgd는/data/misc/pmgd/history.json에서 프로세스 종료를 추적합니다. 데몬은 기기 재부팅당 단일pmgd시작 종료로 프로세스를 제한합니다.
SELinux 구성
프로세스를 모니터링하는 PMGD의 기능은 SELinux 정책에 의해 제한됩니다. 정책에서 허용되지 않는 도메인의 프로세스(예: 공급업체별 시스템 프로세스)를 모니터링하도록 PMGD를 구성하면 PMGD가 이를 모니터링할 수 없으며 logcat에 SELinux 거부가 표시될 수 있습니다.
PMGD가 추가 도메인의 프로세스를 모니터링하도록 허용하려면 PMGD용 기기별 SELinux 정책을 업데이트하여 PMGD의 권한을 확장해야 합니다.
다음은 새 도메인에 대한 액세스를 추가하는 device/<vendor>/<device>/sepolicy/pmgd.te 파일의 예입니다.
# Allow pmgd to access vendor_system_apps
r_dir_file(pmgd, vendor_system_apps)
기기별 정책 작성에 관한 자세한 내용은 SELinux 구현을 참고하세요.
공급업체 정의 구성
PMGD 구성은 공급업체에 의해 주도되며 필수 JSON 파일 /vendor/etc/pmgd/config.json로 구성됩니다. 여기에는 추적할 프로세스, 구성된 메모리 제한 프로필 (cgroup 작업 프로필 사용) 및 메가바이트 단위의 하드 익명 메모리 제한이 나열됩니다.
공급업체 구성 필드
제공된 JSON 구성은 다음 필드로 정의된 프로세스 및 제한 목록입니다.
| 필드 | 유형 | 필수 | 설명 | 기본값 |
|---|---|---|---|---|
target_cmd |
문자열 | 예 | 모니터링할 타겟 프로세스의 명령어 이름입니다(예: system_server). |
해당 사항 없음 |
uid |
정수 | 아니요 | 프로세스의 사용자 ID (UID)입니다. 생략하면 pmgd가 target_cmd와 일치하는 모든 프로세스에 규칙을 전역적으로 적용합니다. |
해당 사항 없음 |
reclaim_wait_time_secs |
정수 | 아니요 | 메모리 한도를 다시 평가하기 전에 시스템이 메모리를 회수할 때까지 기다리는 유예 기간(초)입니다. | 5 |
mem_limit_profile |
문자열 | 예 | `memory.high`를 설정하는 cgroup 작업 프로필의 이름입니다. 이는 프로세스 메모리 제한을 설정하는 데 사용됩니다. | 해당 사항 없음 |
anon_limit_in_mb |
정수 | 예 | 최종 익명 메모리 한도(MB)입니다. 익명 메모리 사용량이 이 값을 초과하면 pmgd가 즉시 프로세스를 종료합니다. |
해당 사항 없음 |
additional_task_profiles |
문자열 목록 | 아니요 | 모니터링이 시작될 때 pmgd가 프로세스에 적용되는 추가 작업 프로필 목록입니다. |
빈 목록 |
다음은 vendor/etc/task_profiles.json의 cgroup 작업 프로필 구성 예시입니다.
{
"Attributes": [
...
{
"Name": "MemHigh",
"Controller": "memory",
"File": "memory.high"
}
],
"Profiles": [
{
"Name": "SystemServerMemoryHighLimit",
"Actions": [
{
"Name": "SetAttribute",
"Params":
{
"Name": "MemHigh",
"Value": "1080M"
}
}
]
}
]
}
다음은 vendor/etc/pmgd/config.json의 PMGD 구성 예시입니다.
{
"targets": [
{
"target_cmd": "system_server",
"uid": 1000,
"reclaim_wait_time_secs": 5,
"mem_limit_profile": "SystemServerMemoryHighLimit",
"anon_limit_in_mb": 300
}
]
}