บันทึกฮีพดัมพ์

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

หน้านี้จะอธิบายเครื่องมือที่ 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