หน่วยความจำเป็นทรัพยากรที่สำคัญและมีอยู่อย่างจำกัดในอุปกรณ์ที่ทำงานด้วยระบบ Android ในฐานะนักพัฒนาแพลตฟอร์ม Android หรือ OEM การทำความเข้าใจวิธีการทำงานของหน่วยความจำในทุกระดับ ตั้งแต่รันไทม์ Java ไปจนถึงเคอร์เนล Linux เป็นสิ่งสำคัญในการสร้างระบบที่มีประสิทธิภาพและเสถียร
คู่มือนี้จะให้ภาพรวมที่ครอบคลุมเกี่ยวกับสถาปัตยกรรมหน่วยความจำของ Android, เครื่องมือที่พร้อมใช้งานสำหรับการวิเคราะห์ และแบบฝึกหัดที่นำไปใช้ได้จริงเพื่อช่วยคุณระบุและแก้ไขปัญหาที่เกี่ยวข้องกับหน่วยความจำ
วัตถุประสงค์
หลังจากอ่านคู่มือนี้จนจบ คุณจะสามารถทำสิ่งต่อไปนี้ได้
- อธิบายแนวคิดพื้นฐานของหน่วยความจำ Android รวมถึงโมเดลกระบวนการ Zygote และไฟล์ที่แมปหน่วยความจำ
- แยกความแตกต่างระหว่าง Resident Set Size (RSS), Proportional Set Size (PSS) และ Unique Set Size (USS)
- ใช้เครื่องมือบรรทัดคำสั่งมาตรฐาน เช่น
dumpsys meminfoและshowmapเพื่อประเมินการใช้งานหน่วยความจำอย่างรวดเร็ว - บันทึกและวิเคราะห์ฮีปดัมป์ของ Java โดยใช้ AHAT เพื่อค้นหาการรั่วไหลและการจัดสรรที่มากเกินไป
- ใช้ Perfetto และ
heapprofdเพื่อทำโปรไฟล์ทั้งหน่วยความจำ Java และหน่วยความจำแบบเนทีฟในทั้งระบบ - ทำความเข้าใจตัวบ่งชี้การใช้หน่วยความจำทั่วทั้งระบบ เช่น Pressure Stall Information (PSI) และตรวจสอบกิจกรรม Low Memory Killer (LMK)
- สังเกตกิจกรรมการเรียกคืนระดับเคอร์เนล ซึ่งรวมถึงการสลับ ZRAM และการขับไล่แคชหน้าเว็บ
โครงสร้างคำแนะนำ
คู่มือนี้แบ่งออกเป็นส่วนต่างๆ ต่อไปนี้ ซึ่งออกแบบมาให้อ่านตามลำดับ
- แนวคิดพื้นฐาน: หลักการทางเทคนิคหลักของหน่วยความจำ Android
- เครื่องมือประเมินผลแบบรวดเร็ว: การใช้
meminfo,showmapและprocstatsเพื่อคัดแยกอย่างรวดเร็ว - การวิเคราะห์หน่วยความจำ Java: ข้อมูลเจาะลึกฮีป Java ด้วย AHAT
- บิตแมปและหน่วยความจำ: ทำความเข้าใจว่ารูปภาพส่งผลต่อ RAM อย่างไรและใช้เครื่องมือเพื่อวิเคราะห์รูปภาพ
- การวิเคราะห์หน่วยความจำแบบเนทีฟ: การทำโปรไฟล์หน่วยความจำ C/C++ ด้วย Perfetto และ
heapprofd - WebView และหน่วยความจำ: ทำความเข้าใจสถาปัตยกรรมแบบหลายกระบวนการและหน่วยความจำที่ใช้ของ WebView
- โค้ดแอปคือหน่วยความจำ: ทำความเข้าใจว่าการโหลดคลาสและ Dex Bloat ส่งผลต่อ RAM อย่างไร
- ชุดข้อความและหน่วยความจำ: การวิเคราะห์ต้นทุนของสแต็กชุดข้อความแบบเนทีฟ
- ตำแหน่งหน่วยความจำและประสิทธิภาพ: ทำความเข้าใจว่ารูปแบบการเข้าถึงข้อมูลส่งผลต่อประสิทธิภาพของ CPU อย่างไร
- การผูกบริการและสถานะกระบวนการ: ทำความเข้าใจว่าทรัพยากร Dependency ข้ามกระบวนการส่งผลต่อคะแนน OOM อย่างไร
- การแก้ปัญหาทั้งระบบ: การตรวจสอบ PSI, LMK, การสลับ ZRAM และการขับไล่แคชของหน้าเว็บ
- การเรียกคืนหน่วยความจำ: การขับออกและการสลับ: ทำความเข้าใจ memcg, การเรียกเก็บเงิน และการเรียกคืนเชิงรุกด้วย
memory.reclaim - การโต้ตอบระหว่าง kswapd และ lmkd: ทำความเข้าใจวิธีการทำงานร่วมกันของ kswapd และ lmkd ภายใต้แรงกดดัน
- คืนหน้าหน่วยความจำไปยังระบบปฏิบัติการ: การใช้
madviseและposix_fadviseเพื่อคืนหน้าฮีปและหน้าแคชไฟล์ที่ไม่ได้ใช้ไปยังเคอร์เนล - คงการทำงานเบื้องหลังไว้ด้วยกระบวนการที่ใช้ทรัพยากรน้อย: การย้ายบริการที่ทำงานอยู่เบื้องหลังและเวิร์กเกอร์ไปยังกระบวนการเฉพาะ เพื่อไม่ให้ UI และหน่วยความจำกราฟิกมีลำดับความสำคัญสูงขึ้น
สิ่งที่ต้องดำเนินการก่อนและสภาพแวดล้อม
คู่มือนี้จะแสดงเวิร์กโฟลว์อ้างอิง ข้อมูลการเปรียบเทียบ และกรณีศึกษาที่สาธิตวิธีวิเคราะห์และแก้ไขปัญหาหน่วยความจำของ Android
- เครื่องมือวิเคราะห์: เทคนิคในคู่มือนี้ใช้เครื่องมือประสิทธิภาพ Android มาตรฐานเป็นหลัก ซึ่งรวมถึง Perfetto,
dumpsys meminfo,showmapและ AHAT - สิทธิ์ระดับรูท: เวิร์กโฟลว์การวินิจฉัยระดับระบบบางอย่าง (เช่น การตรวจสอบแรงดันหน่วยความจำเคอร์เนลหรือตัวนับ PMU ของฮาร์ดแวร์) ต้องใช้สิทธิ์ระดับรูทที่ยกระดับ (
adb root) ในอุปกรณ์ userdebug หรือบิลด์โปรแกรมจำลอง
เริ่มต้นที่นี่: แนวคิดพื้นฐาน