Process memory guardian daemon

Android 17 ขึ้นไปรองรับ Daemon ผู้พิทักษ์หน่วยความจำของกระบวนการ (PMGD) ซึ่งจะปกป้อง สุขภาพของระบบและ ประสบการณ์ของผู้ใช้ด้วยการจัดการการใช้งานหน่วยความจำในเชิงรุกตามกระบวนการ Daemon จะปรับปรุงความเสถียรโดยรวมของอุปกรณ์ด้วยการบังคับใช้ขีดจำกัดหน่วยความจำ อย่างราบรื่นในกระบวนการเป้าหมายที่เฉพาะเจาะจง เพื่อยืนยันว่าการรั่วไหลของหน่วยความจำที่แยกออกมา หรือการเพิ่มขึ้นอย่างรวดเร็วจะไม่ทำให้ประสิทธิภาพของระบบโดยรวมลดลง

แม้ว่าตัวจัดการกระบวนการที่มีหน่วยความจำเหลือน้อยทั่วโลกแบบเดิมจะทำงานเฉพาะเมื่อทั้งระบบอยู่ภายใต้แรงกดดัน แต่ PMGD จะใช้แนวทางแบบละเอียด Daemon จะดำเนินการนี้ โดยการตรวจสอบค่าหน่วยความจำของ Control Group v2 สำหรับกระบวนการเป้าหมาย เมื่อกระบวนการเป้าหมายใช้หน่วยความจำเกินขีดจำกัดที่กำหนดค่าไว้ pmgd จะจัดการการละเมิดขีดจำกัดโดยการบันทึกอะตอมหน่วยความจำ Statsd ก่อนที่จะสิ้นสุด กระบวนการ

วิธีการทำงาน

Daemon ใช้ inotify เพื่อรอรับเหตุการณ์แรงดันหน่วยความจำ (โดยเฉพาะ กิจกรรมที่มีการใช้หน่วยความจำสูงโดยใช้ memory.events) เมื่อกระบวนการที่ตรวจสอบทริกเกอร์ เหตุการณ์หน่วยความจำ pmgd จะดำเนินการต่อไปนี้

  1. การตรวจสอบหน่วยความจำแบบไม่ระบุตัวตน: ประเมินหน่วยความจำแบบไม่ระบุตัวตนของกระบวนการ หากเกินanon_limit_in_mbที่กำหนดค่าไว้ pmgd จะหยุดกระบวนการทันที
  2. ระยะเวลารอการเรียกคืน: หากหน่วยความจำที่ไม่ระบุตัวตนอยู่ภายใต้ขีดจำกัดหน่วยความจำที่ไม่ระบุตัวตนที่ระบุ pmgd จะรอระยะเวลาผ่อนผันการเรียกคืนของระบบ (reclaim_wait_time_secs)
  3. การประเมินหน่วยความจำหลังจากการเรียกคืน: หาก memory.currentของกระบวนการเป้าหมายยังคงมากกว่าหรือเท่ากับ memory.high หลังจาก ระยะเวลาผ่อนผัน หรือหน่วยความจำที่ไม่ระบุตัวตนเกิน anon_limit_in_mb pmgd จะหยุดกระบวนการทันที

โดยจะดำเนินการอย่างต่อเนื่องจนกว่าจะมีการสิ้นสุดกระบวนการหรือการเรียกคืนในกระบวนการ จะลดการใช้งานหน่วยความจำของกระบวนการนั้นๆ ให้อยู่ต่ำกว่าขีดจำกัดหน่วยความจำที่ระบุ

ฟีเจอร์สถานะของระบบ

  • การจำกัดอัตราการรีบูต: เพื่อป้องกันการรีบูตวนซ้ำหรือการขัดข้องอย่างต่อเนื่อง pmgd จะติดตามการสิ้นสุดกระบวนการใน /data/misc/pmgd/history.json Daemon จำกัดกระบวนการให้มีการpmgdสิ้นสุดที่เริ่มต้นเพียงครั้งเดียวต่อการรีบูตอุปกรณ์

การกำหนดค่า SELinux

ความสามารถของ PMGD ในการตรวจสอบกระบวนการถูกจำกัดโดยนโยบาย SELinux หากคุณกำหนดค่า PMGD ให้ตรวจสอบกระบวนการที่นโยบายไม่อนุญาตโดเมน เช่น กระบวนการของระบบที่เฉพาะเจาะจงของผู้ให้บริการ PMGD จะตรวจสอบไม่ได้ และคุณอาจเห็นการปฏิเสธ SELinux ใน Logcat

หากต้องการอนุญาตให้ 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 จำนวนเต็ม ไม่ รหัสผู้ใช้ (UID) ของกระบวนการ หากไม่ระบุ pmgd จะใช้ กฎกับกระบวนการใดก็ตามที่ตรงกับ target_cmd ทั่วโลก ไม่มี
reclaim_wait_time_secs จำนวนเต็ม ไม่ ระยะเวลาผ่อนผันเป็นวินาทีที่รอก่อนให้ระบบเรียกคืนหน่วยความจำ ก่อนที่จะประเมินขีดจำกัดหน่วยความจำอีกครั้ง 5
mem_limit_profile สตริง ใช่ ชื่อของโปรไฟล์งาน cgroup ที่ตั้งค่า `memory.high` ใช้เพื่อกำหนดขีดจำกัดหน่วยความจำของกระบวนการ ไม่มี
anon_limit_in_mb จำนวนเต็ม ใช่ ขีดจำกัดหน่วยความจำแบบไม่ระบุตัวตนสูงสุดในหน่วยเมกะไบต์ หากการใช้งานหน่วยความจำที่ไม่ระบุตัวตน เกินค่านี้ pmgd จะหยุดกระบวนการ ทันที ไม่มี
additional_task_profiles รายการสตริง ไม่ รายการโปรไฟล์งานเพิ่มเติมที่ pmgd ใช้กับ กระบวนการเมื่อการตรวจสอบเริ่มต้นขึ้น รายการที่ว่างเปล่า

ต่อไปนี้คือตัวอย่างการกำหนดค่าโปรไฟล์งาน cgroup ใน vendor/etc/task_profiles.json

{
  "Attributes": [
    ...
    {
      "Name": "MemHigh",
      "Controller": "memory",
      "File": "memory.high"
    }
  ],
  "Profiles": [
    {
      "Name": "SystemServerMemoryHighLimit",
      "Actions": [
        {
          "Name": "SetAttribute",
          "Params":
          {
            "Name": "MemHigh",
            "Value": "1080M"
          }
        }
      ]
    }
  ]
}

ต่อไปนี้เป็นตัวอย่างการกำหนดค่าของไฟล์กำหนดค่า PMGD ใน vendor/etc/pmgd/config.json

{
  "targets": [
    {
      "target_cmd": "system_server",
      "uid": 1000,
      "reclaim_wait_time_secs": 5,
      "mem_limit_profile": "SystemServerMemoryHighLimit",
      "anon_limit_in_mb": 300
    }
  ]
}