ภาพรวมการจัดการหน่วยความจำ

การใช้เครื่องเสมือน Android Runtime (ART) และ Dalvik การแบ่งหน้า และการแมปหน่วยความจำ (mmapping) เพื่อจัดการหน่วยความจำ หมายความว่าหน่วยความจำใดๆ ที่แอป ไม่ว่าจะด้วยการจัดสรร วัตถุใหม่หรือการแตะหน้าเว็บที่แมป - จะยังอยู่ใน RAM และ ไม่สามารถแบ่งหน้าได้ วิธีเดียวที่จะปล่อยความทรงจำจากแอปได้คือการเผยแพร่ อ้างอิงถึงว่าแอปมีการระงับ ทำให้หน่วยความจำพร้อมใช้งานสำหรับ เครื่องมือเก็บขยะ โดยมีข้อยกเว้นเพียงข้อเดียว คือทุกไฟล์ โจมตีโดยไม่ทำการแก้ไข เช่น โค้ด อาจถูกแบ่งหน้าออกจาก RAM หากระบบต้องการใช้หน่วยความจำนั้นที่อื่น

หน้านี้อธิบายวิธีที่ Android จัดการกระบวนการและหน่วยความจำของแอป การจัดสรร ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดการหน่วยความจำอย่างมีประสิทธิภาพมากขึ้น ในแอปของคุณให้ดู จัดการหน่วยความจำของแอป

บริการเก็บขยะ

สภาพแวดล้อมหน่วยความจำที่มีการจัดการ เช่น เครื่องเสมือน ART หรือ Dalvik ติดตามการจัดสรรหน่วยความจำแต่ละรายการ เมื่อระบุได้แล้ว โปรแกรมจะไม่ใช้ความทรงจำชิ้นหนึ่งอีกต่อไป โปรแกรมเมอร์จะปล่อยตัวกลับเข้าไปในฮีป โดยไม่ต้องมีการแทรกแซงใดๆ จากโปรแกรมเมอร์ กลไกในการเรียกคืนหน่วยความจำที่ไม่ได้ใช้ภายในสภาพแวดล้อมหน่วยความจำที่มีการจัดการเรียกว่าการเก็บขยะ การเก็บขยะมีเป้าหมาย 2 ประการดังนี้ ค้นหาออบเจ็กต์ข้อมูลในโปรแกรมที่เข้าถึงไม่ได้ในอนาคต และ เรียกคืนทรัพยากรที่ออบเจ็กต์ใช้

หน่วยความจำของ Android คือรุ่นที่มีหลายรุ่น ซึ่งหมายความว่า มีที่เก็บข้อมูลการจัดสรรที่แตกต่างกันที่ติดตาม ตามอายุการใช้งานที่คาดไว้และขนาดของออบเจ็กต์ที่จัดสรร ตัวอย่างเช่น ออบเจ็กต์ที่จัดสรรล่าสุดจะอยู่ในรุ่นเยาว์ เมื่อออบเจ็กต์ทำงานมานานพอแล้ว จะได้รับการโปรโมต แก่คนรุ่นเก่า แล้วตามด้วยคนรุ่นใหม่

การสร้างฮีปแต่ละรายการมีขีดจำกัดสูงสุดเฉพาะของตัวเองสำหรับจำนวน ของหน่วยความจำที่ วัตถุสามารถยึดครองได้ เมื่อใดก็ตามที่รุ่นเริ่มเต็ม ระบบจะเรียกใช้เหตุการณ์การเก็บขยะเพื่อพยายามเพิ่มพื้นที่ว่างในหน่วยความจำ ระยะเวลาการจัดเก็บขยะ ขึ้นอยู่กับรุ่นของวัตถุที่กำลังเก็บรวบรวม และจำนวนออบเจ็กต์ที่ใช้งานอยู่ในแต่ละรุ่น

แม้ว่าการเก็บขยะจะทำได้รวดเร็วมาก แต่ก็ยัง ส่งผลต่อประสิทธิภาพแอปของคุณ โดยทั่วไปคุณจะไม่ได้ควบคุม เมื่อเกิดเหตุการณ์การเก็บขยะจากภายในโค้ด ระบบมีชุดเกณฑ์ที่ใช้งานอยู่เพื่อกำหนดเวลาที่ควรดำเนินการ กับระบบเก็บขยะ เมื่อเป็นไปตามเกณฑ์แล้ว ระบบจะหยุดดำเนินการตามกระบวนการและเริ่มเก็บขยะ ถ้า ระบบเก็บขยะเกิดขึ้นในช่วงกลางของลูปการประมวลผลที่หนักหน่วง เช่น ภาพเคลื่อนไหวหรือในระหว่างการเล่นเพลง อาจเพิ่มเวลาในการประมวลผลได้ การเพิ่มขึ้นนี้มีโอกาสผลักดันการเรียกใช้โค้ดในแอปให้พ้นช่วง เกณฑ์ขั้นต่ำ 16 มิลลิวินาทีที่แนะนำ เพื่อการแสดงผลเฟรมที่มีประสิทธิภาพและราบรื่น

นอกจากนี้ โฟลว์โค้ดอาจทำงานประเภทที่ บังคับให้เกิดเหตุการณ์การเก็บขยะ บ่อยขึ้นหรือทำให้มีระยะเวลายาวนานกว่าปกติ ตัวอย่างเช่น หากคุณจัดสรรออบเจ็กต์หลายรายการในฟิลด์ ส่วนด้านในสุดของ for-loop ระหว่างเฟรมของอัลฟ่าแต่ละเฟรม ภาพเคลื่อนไหวผสมผสานกัน คุณอาจทำลายฮีปของความทรงจำด้วย ออบเจ็กต์จำนวนมาก ในสถานการณ์ดังกล่าว พนักงานเก็บขยะดำเนินการจัดการขยะหลายรายการ เหตุการณ์ในคอลเล็กชันและทำให้ประสิทธิภาพของแอปลดลงได้

สำหรับข้อมูลทั่วไปเพิ่มเติมเกี่ยวกับการเก็บขยะ โปรดดูที่ การเก็บขยะ

แชร์ความทรงจำ

เพื่อให้มีข้อมูลเพียงพอใน RAM Android จะพยายามแชร์หน้า RAM ข้ามกระบวนการ ทั้งนี้ ทำได้ด้วยวิธีต่อไปนี้

  • กระบวนการของแอปแต่ละรายการจะแยกออกจากกระบวนการที่มีอยู่ที่เรียกว่า Zygote กระบวนการ Zygote จะเริ่มต้นเมื่อระบบเปิดเครื่องและโหลดตามปกติ โค้ดและทรัพยากรของเฟรมเวิร์ก (เช่น ธีมกิจกรรม) วิธีเริ่มกระบวนการใหม่ของแอป ระบบจะแยกกระบวนการ Zygote แล้ว โหลดและเรียกใช้โค้ดของแอปในกระบวนการใหม่ วิธีนี้จะทำให้หน้า RAM ส่วนใหญ่ที่จัดสรรไว้สำหรับ โค้ดและทรัพยากรของเฟรมเวิร์กที่จะแชร์ในกระบวนการทั้งหมดของแอป
  • ข้อมูลแบบคงที่ส่วนใหญ่จะถูกแทรกด้วยกระบวนการ เทคนิคนี้ช่วยให้สามารถแชร์ข้อมูลได้ ระหว่างกระบวนการต่างๆ และยังอนุญาตให้แบ่งหน้า เมื่อจำเป็น ตัวอย่างข้อมูลแบบคงที่มีดังนี้ รหัส Dalvik (ด้วยการวางโค้ดไว้ใน .odex ที่ลิงก์ไว้ล่วงหน้า) ไฟล์สำหรับการเรียกใช้โดยตรง) ทรัพยากรของแอป (โดยการออกแบบตารางทรัพยากรให้เป็นโครงสร้าง ที่พับเก็บได้ และจัดแนวรหัสไปรษณีย์ รายการ APK) และโปรเจ็กต์ดั้งเดิม เช่น โค้ดแบบเนทีฟในไฟล์ .so
  • ในหลายๆ ที่ Android ก็จะใช้ RAM ในกระบวนการที่ใช้การจัดสรรอย่างชัดแจ้ง ภูมิภาคหน่วยความจำที่ใช้ร่วมกัน (ไม่ว่าจะเป็น Ashmem หรือ Gralloc) เช่น พื้นผิวหน้าต่างใช้ ระหว่างแอปกับเครื่องมือประกอบหน้าจอ และ บัฟเฟอร์เคอร์เซอร์ใช้หน่วยความจำที่ใช้ร่วมกันระหว่าง ผู้ให้บริการเนื้อหาและลูกค้า

เนื่องจากมีการใช้หน่วยความจำร่วมกันอย่างแพร่หลาย การพิจารณา แอปของคุณใช้หน่วยความจำมากเพียงใด การดูแล เทคนิคในการกำหนดแอป มีการพูดคุยถึงการใช้หน่วยความจำใน การตรวจสอบการใช้ RAM

จัดสรรและเรียกคืนหน่วยความจำของแอป

ฮีพ Dalvik จะจำกัดอยู่ที่ ช่วงหน่วยความจำเสมือน 1 ช่วงสำหรับกระบวนการของแอปแต่ละกระบวนการ สิ่งนี้เป็นตัวกำหนด ขนาดฮีปเชิงตรรกะ ซึ่งอาจเพิ่มขึ้นตามความจำเป็น แต่ไม่เกินขีดจํากัดที่ระบบกําหนด สำหรับแต่ละแอป

ขนาดเชิงตรรกะของฮีปไม่เหมือนกับปริมาณหน่วยความจําจริงที่ฮีปใช้ เมื่อตรวจสอบฮีปของแอป Android จะคำนวณ ค่าที่เรียกว่า Proportional Set Size (PSS) ซึ่งรวมทั้งหน้าที่สกปรกและสะอาด ที่ใช้ร่วมกับกระบวนการอื่นๆ แต่มีเฉพาะใน ตามสัดส่วนของจำนวนแอปที่แชร์ RAM นั้น ยอดรวม (PSS) นี้คือจำนวนที่ระบบ คือหน่วยความจำทางกายภาพของคุณ ดูข้อมูลเพิ่มเติมเกี่ยวกับ PSS ได้ที่ การตรวจสอบการใช้ RAM

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

จำกัดหน่วยความจำของแอป

เพื่อรักษาสภาพแวดล้อมการทำงานแบบมัลติทาสก์ Android กำหนดขีดจำกัดขนาดฮีปอย่างเข้มงวด สำหรับแต่ละแอป ขีดจำกัดขนาดฮีปที่แน่นอนจะแตกต่างกันไป ระหว่างอุปกรณ์ตามปริมาณ RAM ที่อุปกรณ์นั้น ที่ใช้ได้โดยรวม หากแอปมีเวอร์ชัน และพยายามจัดสรรเพิ่มเติม ก็รับ OutOfMemoryError ได้

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

เปลี่ยนแอป

เมื่อผู้ใช้สลับใช้แอปต่างๆ Android จะเก็บแอปที่ไม่ได้อยู่เบื้องหน้าไว้ ซึ่งก็คือแอปที่ผู้ใช้มองไม่เห็นหรือไม่ได้เรียกใช้บริการอยู่เบื้องหน้า เช่น การเล่นเพลง ไว้ในแคช ตัวอย่างเช่น เมื่อผู้ใช้เปิดแอปเป็นครั้งแรก ระบบจะสร้างกระบวนการสําหรับแอปนั้น แต่เมื่อผู้ใช้ออกจากแอป กระบวนการดังกล่าวจะไม่หยุด ระบบจะแคชกระบวนการไว้ ถ้า ผู้ใช้กลับไปยังแอปในภายหลัง จากนั้นระบบจะนำกระบวนการดังกล่าวกลับมาใช้ใหม่ ด้วยเหตุนี้ ทำให้เปลี่ยนแอปได้เร็วขึ้น

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

หมายเหตุ: ยิ่งแอปใช้หน่วยความจำน้อยขณะอยู่ในแคช ก็ยิ่งมีโอกาสที่จะไม่ถูกฆ่าตายและสามารถกลับมาทำงานอีกครั้งได้อย่างรวดเร็ว อย่างไรก็ตาม ระบบอาจแคชได้ ทั้งนี้ขึ้นอยู่กับข้อกำหนดของระบบที่ใช้งานโดยทันที กระบวนการถูกยกเลิกได้ทุกเมื่อ ไม่ว่าจะใช้ทรัพยากรก็ตาม

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

การทดสอบความเครียดของหน่วยความจำ

แม้ว่าปัญหาความเครียดของหน่วยความจำจะไม่เกิดขึ้นบ่อยนักในอุปกรณ์ระดับไฮเอนด์ แต่ก็อาจทำให้เกิดปัญหาได้ สำหรับผู้ใช้ที่ใช้อุปกรณ์ที่มี RAM ต่ำ เช่น ผู้ที่ใช้ Android (รุ่น Go) สิ่งสำคัญคือต้องพยายาม ทำซ้ำสภาพแวดล้อมที่ใช้หน่วยความจำนี้ซ้ำเพื่อให้คุณเขียนการทดสอบการใช้เครื่องมือเพื่อยืนยันแอปได้ และปรับปรุงประสบการณ์การใช้งานสำหรับผู้ใช้บนอุปกรณ์ที่มีหน่วยความจำต่ำ

การทดสอบแอปพลิเคชันแบบเข้มงวด

การทดสอบแอปพลิเคชันแบบเข้มงวด (stressapptest) เป็นการทดสอบอินเทอร์เฟซหน่วยความจำที่ช่วยจำลองสถานการณ์ที่มีภาระงานสูงและสมจริงเพื่อทดสอบหน่วยความจำต่างๆ และข้อจำกัดด้านฮาร์ดแวร์สำหรับแอปของคุณ ด้วยความสามารถในการกำหนดเวลาและข้อจำกัดด้านหน่วยความจำ ช่วยให้คุณสามารถเขียนเครื่องมือวัดเพื่อตรวจสอบการเผชิญหน้ากับสถานการณ์ที่มีหน่วยความจำสูงในชีวิตจริง ตัวอย่างเช่น ใช้ชุดคำสั่งต่อไปนี้เพื่อพุชไลบรารีแบบคงที่ในระบบไฟล์ข้อมูล ให้เป็นไฟล์ปฏิบัติการ และทำการทดสอบความเครียดเป็นเวลา 20 วินาทีที่ 990 MB
    adb push stressapptest /data/local/tmp/
    adb shell chmod 777 /data/local/tmp/stressapptest
    adb shell /data/local/tmp/stressapptest -s 20 -M 990

  

โปรดดูstressapptest สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการติดตั้งเครื่องมือ อาร์กิวเมนต์ทั่วไป และการจัดการข้อผิดพลาด

การสังเกตการณ์ใน stressapptest

เครื่องมืออย่างเช่น stressapptest สามารถใช้เพื่อขอการจัดสรรหน่วยความจำที่มีขนาดใหญ่กว่าได้อย่างอิสระ พร้อมใช้งาน คำขอประเภทนี้สามารถทำให้เกิดการแจ้งเตือนได้หลายอย่าง ซึ่งคุณควรทราบจาก ด้านการพัฒนา การแจ้งเตือนหลัก 3 ประการที่อาจเพิ่มขึ้นเนื่องจากหน่วยความจำเหลือน้อย ได้แก่
  • SIGABRT: นี่เป็นการขัดข้องของระบบที่ร้ายแรงสำหรับกระบวนการของคุณเนื่องจากมีการขอการจัดสรร มีขนาดใหญ่กว่าหน่วยความจำที่ว่าง แต่ระบบมีหน่วยความจำไม่พอ
  • SIGQUIT: จะสร้างดัมพ์หน่วยความจำหลักและสิ้นสุดกระบวนการเมื่อตรวจพบโดยการทดสอบการใช้เครื่องมือของคุณ
  • TRIM_MEMORY_EVENTS: Callback เหล่านี้พร้อมใช้งานบน Android 4.1 (API ระดับ 16) ขึ้นไป และให้รายละเอียด หน่วยความจำของระบบสำหรับกระบวนการของคุณ