บันทึกฮีปดัมพ์เพื่อดูว่าออบเจ็กต์ใดในแอปที่ใช้หน่วยความจํา ณ เวลาบันทึก และระบุการรั่วไหลของหน่วยความจําหรือลักษณะการจัดสรรหน่วยความจําที่ทําให้แอปกระตุก ค้าง หรือแม้แต่ขัดข้อง ซึ่งจะมีประโยชน์อย่างยิ่งในการถ่ายโอนข้อมูลกองหลังจากเซสชันของผู้ใช้ที่ขยายเวลาออกไป เมื่อระบบอาจแสดงออบเจ็กต์ที่ยังคงอยู่ในหน่วยความจำซึ่งไม่ควรอยู่อีกต่อไป
หน้านี้จะอธิบายเครื่องมือที่ Android Studio มีให้เพื่อรวบรวมและวิเคราะห์กองข้อมูล หรือจะตรวจสอบหน่วยความจำของแอปจากบรรทัดคำสั่งด้วย dumpsys
และดูเหตุการณ์การเก็บขยะ (GC) ใน Logcat ก็ได้
เหตุผลที่ควรวิเคราะห์หน่วยความจําของแอป
Android มีสภาพแวดล้อมหน่วยความจำที่มีการจัดการ เมื่อ Android พิจารณาว่าแอปของคุณไม่ได้ใช้ออบเจ็กต์บางรายการแล้ว ตัวเก็บขยะจะปล่อยหน่วยความจำที่ไม่ได้ใช้กลับไปยังกอง Android ปรับปรุงวิธีค้นหาหน่วยความจำที่ไม่ได้ใช้อยู่อย่างต่อเนื่อง แต่บางครั้งใน Android ทุกเวอร์ชัน ระบบจะต้องหยุดโค้ดของคุณชั่วคราว ส่วนใหญ่แล้ว ผู้ใช้จะไม่เห็นการหยุดชั่วคราว อย่างไรก็ตาม หากแอปของคุณจัดสรรหน่วยความจำเร็วกว่าที่ระบบจะรวบรวมได้ แอปอาจทำงานล่าช้าขณะที่เครื่องมือรวบรวมหน่วยความจำเพิ่มพื้นที่หน่วยความจำให้เพียงพอสำหรับการจัดสรรของคุณ ความล่าช้าอาจทําให้แอปข้ามเฟรมและทําให้แอปทำงานช้าอย่างเห็นได้ชัด
แม้ว่าแอปจะไม่ทำงานช้า แต่หากมีการรั่วไหลของหน่วยความจำ แอปจะยังคงใช้หน่วยความจำนั้นอยู่แม้ว่าจะทำงานอยู่เบื้องหลังก็ตาม ลักษณะการทำงานนี้อาจทำให้ประสิทธิภาพหน่วยความจำที่เหลือของระบบช้าลงด้วยการบังคับให้เหตุการณ์การเก็บขยะที่ไม่จำเป็นเกิดขึ้น ในที่สุด ระบบจะบังคับให้หยุดกระบวนการของแอปเพื่อเรียกคืนหน่วยความจำ จากนั้นเมื่อผู้ใช้กลับมาที่แอป กระบวนการของแอปจะต้องเริ่มต้นใหม่ทั้งหมด
ดูข้อมูลเกี่ยวกับแนวทางปฏิบัติด้านการเขียนโปรแกรมที่สามารถลดการใช้หน่วยความจำของแอปได้ที่จัดการหน่วยความจำของแอป
ภาพรวมของฮีปดัมป์
หากต้องการบันทึกฮีปดัมป์ ให้เลือกงานวิเคราะห์การใช้งานหน่วยความจํา (ฮีปดัมป์) (ใช้เครื่องมือวิเคราะห์ประสิทธิภาพ: เรียกใช้ "app" แบบแก้ไขข้อบกพร่องได้ (ข้อมูลสมบูรณ์)) เพื่อบันทึกฮีปดัมป์ ขณะถ่ายโอนข้อมูลฮีป ปริมาณหน่วยความจํา Java อาจเพิ่มขึ้นชั่วคราว กรณีนี้เป็นเรื่องปกติเนื่องจากฮีปดัมป์เกิดขึ้นในกระบวนการเดียวกับแอปของคุณและต้องใช้หน่วยความจําบางส่วนเพื่อรวบรวมข้อมูล หลังจากบันทึกไฟล์การถ่ายโอนข้อมูลกองขยะแล้ว คุณจะเห็นข้อมูลต่อไปนี้
รายการชั้นเรียนจะแสดงข้อมูลต่อไปนี้
- การจัดสรร: จํานวนการจัดสรรในกอง
ขนาดเนทีฟ: จำนวนหน่วยความจำเนทีฟทั้งหมดที่ใช้โดยออบเจ็กต์ประเภทนี้ (เป็นไบต์) คุณจะเห็นหน่วยความจําสําหรับออบเจ็กต์บางรายการที่จัดสรรใน Java เนื่องจาก Android ใช้หน่วยความจําเนทีฟสําหรับคลาสเฟรมเวิร์กบางคลาส เช่น
Bitmap
ขนาดแบบตื้น: จํานวนหน่วยความจํา Java ทั้งหมดที่ออบเจ็กต์ประเภทนี้ใช้ (เป็นไบต์)
ขนาดที่คงไว้: ขนาดหน่วยความจําทั้งหมดที่คงไว้เนื่องจากอินสแตนซ์ทั้งหมดของคลาสนี้ (เป็นไบต์)
ใช้เมนูกองเพื่อกรองกองที่ต้องการ
- กองขยะของแอป (ค่าเริ่มต้น): กองขยะหลักที่แอปจัดสรรหน่วยความจำ
- กอง heap ของรูปภาพ: อิมเมจการบูตของระบบซึ่งมีคลาสที่โหลดไว้ล่วงหน้าขณะบูต การจัดสรรในส่วนนี้จะไม่มีการย้ายหรือหายไป
- กอง Zygote: กอง Copy-On-Write ที่แยกกระบวนการแอปออกจากระบบ Android
ใช้เมนูแบบเลื่อนลงของการจัดเรียงเพื่อเลือกวิธีจัดสรร
- จัดเรียงตามชั้นเรียน (ค่าเริ่มต้น): จัดกลุ่มการจัดสรรทั้งหมดตามชื่อชั้นเรียน
- จัดเรียงตามแพ็กเกจ: จัดกลุ่มการจัดสรรทั้งหมดตามชื่อแพ็กเกจ
ใช้เมนูแบบเลื่อนลงของชั้นเรียนเพื่อกรองกลุ่มชั้นเรียน ดังนี้
- คลาสทั้งหมด (ค่าเริ่มต้น): แสดงคลาสทั้งหมด รวมถึงคลาสจากไลบรารีและ Dependency
- แสดงการรั่วไหลของกิจกรรม/เศษข้อมูล: แสดงคลาสที่ทำให้เกิดการรั่วไหลของหน่วยความจำ
- แสดงคลาสโปรเจ็กต์: แสดงเฉพาะคลาสที่โปรเจ็กต์ของคุณกำหนด
คลิกชื่อคลาสเพื่อเปิดแผงอินสแตนซ์ อินสแตนซ์แต่ละรายการที่แสดงจะมีข้อมูลต่อไปนี้
- ความลึก: จำนวน Hop ที่สั้นที่สุดจากรูท GC ไปยังอินสแตนซ์ที่เลือก
- ขนาดเนทีฟ: ขนาดของอินสแตนซ์นี้ในหน่วยความจําเนทีฟ คอลัมน์นี้จะแสดงใน Android 7.0 ขึ้นไปเท่านั้น
- ขนาดระดับออบเจ็กต์: ขนาดของอินสแตนซ์นี้ในหน่วยความจำ Java
- ขนาดที่เก็บไว้: ขนาดหน่วยความจําที่อินสแตนซ์นี้ใช้มากที่สุด (ตามต้นไม้โดมิเนเตอร์)
คลิกอินสแตนซ์เพื่อแสดงรายละเอียดอินสแตนซ์ ซึ่งรวมถึงช่องและข้อมูลอ้างอิง ฟิลด์และประเภทข้อมูลอ้างอิงทั่วไปคือประเภทที่มีโครงสร้าง , อาร์เรย์ , และประเภทข้อมูลพื้นฐาน ใน Java คลิกขวาที่ช่องหรือข้อมูลอ้างอิงเพื่อไปยังอินสแตนซ์หรือบรรทัดที่เชื่อมโยงในซอร์สโค้ด
- ช่อง: แสดงช่องทั้งหมดในอินสแตนซ์นี้
- การอ้างอิง: แสดงการอ้างอิงทั้งหมดไปยังออบเจ็กต์ที่ไฮไลต์ในแท็บอินสแตนซ์
ค้นหาหน่วยความจำที่รั่วไหล
หากต้องการกรองไปยังคลาสที่อาจเชื่อมโยงกับการรั่วไหลของหน่วยความจำอย่างรวดเร็ว ให้เปิดเมนูแบบเลื่อนลงของคลาสแล้วเลือกแสดงการรั่วไหลของกิจกรรม/เศษ Android Studio จะแสดงคลาสที่คิดว่าบ่งบอกถึงการรั่วไหลของหน่วยความจำสำหรับอินสแตนซ์ Activity
และ Fragment
ในแอปของคุณ ประเภทข้อมูลซึ่งตัวกรองแสดงมีดังนี้
- อินสแตนซ์
Activity
ที่ถูกทำลายแล้วแต่ยังคงมีการอ้างอิง - อินสแตนซ์
Fragment
ที่ไม่มีFragmentManager
ที่ถูกต้องแต่ยังคงมีการอ้างอิง
โปรดทราบว่าตัวกรองอาจให้ผลบวกลวงในสถานการณ์ต่อไปนี้
- มีการสร้าง
Fragment
แล้วแต่ยังไม่ได้ใช้งาน - ระบบแคช
Fragment
ไว้ แต่ไม่ได้เป็นส่วนหนึ่งของFragmentTransaction
หากต้องการค้นหาการรั่วไหลของหน่วยความจําด้วยตนเอง ให้เรียกดูรายการคลาสและอินสแตนซ์เพื่อค้นหาออบเจ็กต์ที่มีขนาดที่เก็บไว้ขนาดใหญ่ มองหาหน่วยความจําที่รั่วไหลซึ่งเกิดจากสาเหตุต่อไปนี้
- การอ้างอิง
Activity
แบบถาวร,Context
,View
,Drawable
และออบเจ็กต์อื่นๆ ที่อาจมีข้อมูลอ้างอิงถึงคอนเทนเนอร์Activity
หรือContext
- คลาสภายในแบบไม่คงที่ เช่น
Runnable
ซึ่งเก็บอินสแตนซ์Activity
ได้ - แคชที่เก็บออบเจ็กต์ไว้นานกว่าที่จำเป็น
เมื่อพบการสูญเสียหน่วยความจำที่อาจเกิดขึ้น ให้ใช้แท็บช่องและข้อมูลอ้างอิงในรายละเอียดอินสแตนซ์เพื่อไปยังอินสแตนซ์หรือบรรทัดโค้ดต้นทางที่ต้องการ
ทริกเกอร์หน่วยความจำที่รั่วสำหรับการทดสอบ
หากต้องการวิเคราะห์การใช้หน่วยความจำ คุณควรทดสอบโค้ดแอปและพยายามบังคับให้หน่วยความจำรั่ว วิธีหนึ่งในการกระตุ้นให้เกิดการรั่วไหลของหน่วยความจำในแอปคือการปล่อยให้แอปทำงานไปสักพักก่อนตรวจสอบกอง การรั่วไหลอาจเพิ่มขึ้นไปยังด้านบนของการจัดสรรในกอง อย่างไรก็ตาม ยิ่งการรั่วไหลมีขนาดเล็ก คุณก็จะต้องเรียกใช้แอปนานขึ้นเพื่อดูการรั่วไหล
นอกจากนี้ คุณยังทริกเกอร์การรั่วไหลของหน่วยความจำได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
- หมุนอุปกรณ์จากแนวตั้งเป็นแนวนอนและกลับเป็นแนวตั้งหลายครั้งขณะอยู่ในสถานะกิจกรรมต่างๆ การหมุนอุปกรณ์มักทําให้แอปรั่วออบเจ็กต์
Activity
,Context
หรือView
เนื่องจากระบบจะสร้างActivity
ขึ้นมาใหม่ และหากแอปของคุณเก็บข้อมูลอ้างอิงออบเจ็กต์ดังกล่าวไว้ที่อื่น ระบบจะเก็บขยะไม่ได้ - สลับไปมาระหว่างแอปของคุณกับแอปอื่นขณะอยู่ในสถานะกิจกรรมที่แตกต่างกัน เช่น ไปยังหน้าจอหลัก แล้วกลับไปที่แอป
ส่งออกและนำเข้าไฟล์บันทึกการดัมพ์กอง heap
คุณสามารถส่งออกและนําเข้าไฟล์การดัมพ์กองจากแท็บไฟล์บันทึกที่ผ่านมาในเครื่องมือวิเคราะห์โปรไฟล์ Android Studio จะบันทึกไฟล์บันทึกเป็นไฟล์ .hprof
หรือหากต้องการใช้เครื่องมือวิเคราะห์ไฟล์ .hprof
อื่น เช่น jhat คุณจะต้องแปลงไฟล์ .hprof
จากรูปแบบ Android เป็นรูปแบบไฟล์ Java SE.hprof
หากต้องการแปลงรูปแบบไฟล์ ให้ใช้hprof-conv
เครื่องมือ
ที่มีให้ในไดเรกทอรี {android_sdk}/platform-tools/
เรียกใช้คำสั่ง hprof-conv
พร้อมอาร์กิวเมนต์ 2 รายการ ได้แก่ ชื่อไฟล์ .hprof
ต้นฉบับและตำแหน่งที่จะเขียนไฟล์ .hprof
ที่แปลง รวมถึงชื่อไฟล์ .hprof
ใหม่ เช่น
hprof-conv heap-original.hprof heap-converted.hprof