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

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

หน้านี้จะอธิบายเครื่องมือที่ Android Studio มีให้เพื่อรวบรวมและวิเคราะห์กองข้อมูล หรือจะตรวจสอบหน่วยความจำของแอปจากบรรทัดคำสั่งด้วย dumpsys และดูเหตุการณ์การเก็บขยะ (GC) ใน Logcat ก็ได้

เหตุผลที่ควรวิเคราะห์หน่วยความจําของแอป

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

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

ดูข้อมูลเกี่ยวกับแนวทางปฏิบัติด้านการเขียนโปรแกรมที่สามารถลดการใช้หน่วยความจำของแอปได้ที่จัดการหน่วยความจำของแอป

ภาพรวมของฮีปดัมป์

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

รายการชั้นเรียนจะแสดงข้อมูลต่อไปนี้

  • การจัดสรร: จํานวนการจัดสรรในกอง
  • ขนาดเนทีฟ: จำนวนหน่วยความจำเนทีฟทั้งหมดที่ใช้โดยออบเจ็กต์ประเภทนี้ (เป็นไบต์) คุณจะเห็นหน่วยความจำที่นี่สำหรับออบเจ็กต์บางรายการที่จัดสรรใน Java เนื่องจาก Android ใช้หน่วยความจำในเครื่องสำหรับคลาสเฟรมเวิร์กบางคลาส เช่น Bitmap

  • ขนาดระดับออบเจ็กต์: ปริมาณหน่วยความจำทั้งหมดของ Java ที่ออบเจ็กต์ประเภทนี้ใช้ (ใน ไบต์)

  • ขนาดที่คงไว้: ขนาดทั้งหมดของหน่วยความจำที่เก็บรักษาไว้เนื่องจากอินสแตนซ์ทั้งหมดของ คลาสนี้ (ในหน่วยไบต์)

ใช้เมนูกองเพื่อกรองกองที่เฉพาะเจาะจง ดังนี้

  • กองขยะของแอป (ค่าเริ่มต้น): กองขยะหลักที่แอปจัดสรรหน่วยความจำ
  • ฮีปอิมเมจ: อิมเมจเปิดเครื่องของระบบซึ่งมีคลาสที่โหลดไว้ล่วงหน้า ระหว่างเวลาเปิดเครื่อง การจัดสรรในส่วนนี้จะไม่มีการย้ายหรือหายไป
  • กอง Zygote: กอง Copy-On-Write ที่แยกกระบวนการแอปออกจากระบบ Android

ใช้เมนูแบบเลื่อนลง "จัดเรียง" เพื่อเลือกวิธีจัดเรียงการจัดสรร ดังนี้

  • จัดเรียงตามชั้นเรียน (ค่าเริ่มต้น): จัดกลุ่มการจัดสรรทั้งหมดตามชื่อชั้นเรียน
  • จัดเรียงตามแพ็กเกจ: จัดกลุ่มการจัดสรรทั้งหมดตามชื่อแพ็กเกจ

ใช้เมนูแบบเลื่อนลงของชั้นเรียนเพื่อกรองกลุ่มชั้นเรียน ดังนี้

  • คลาสทั้งหมด (ค่าเริ่มต้น): แสดงคลาสทั้งหมด รวมถึงคลาสจากไลบรารีและ Dependency
  • แสดงกิจกรรม/การรั่วไหลของส่วนย่อย: แสดงคลาสที่ทำให้หน่วยความจำรั่วไหล
  • แสดงคลาสโปรเจ็กต์: แสดงเฉพาะคลาสที่โปรเจ็กต์กำหนด

คลิกชื่อคลาสเพื่อเปิดแผงอินสแตนซ์ อินสแตนซ์แต่ละรายการที่แสดงจะมีข้อมูลต่อไปนี้

  • ความลึก: จำนวน Hop ที่สั้นที่สุดจากรูท GC ไปยังอินสแตนซ์ที่เลือก
  • ขนาดเนทีฟ: ขนาดของอินสแตนซ์นี้ในหน่วยความจําเนทีฟ คอลัมน์นี้ มองเห็นได้สำหรับ Android 7.0 ขึ้นไปเท่านั้น
  • ขนาดระดับออบเจ็กต์: ขนาดของอินสแตนซ์นี้ในหน่วยความจำ Java
  • ขนาดที่คงไว้: ขนาดของหน่วยความจำที่อินสแตนซ์นี้มีผล (ตาม Dominator Tree)

คลิกอินสแตนซ์เพื่อแสดงรายละเอียดอินสแตนซ์ รวมถึงช่องของอินสแตนซ์ และข้อมูลอ้างอิง ช่องและข้อมูลอ้างอิงประเภททั่วไปเป็นประเภทที่มีโครงสร้าง อาร์เรย์ , และข้อมูลพื้นฐาน ใน Java คลิกขวาที่ช่องหรือการอ้างอิงเพื่อไปยังอินสแตนซ์ที่เชื่อมโยง หรือ ในซอร์สโค้ด

  • ช่อง: แสดงทุกช่องในอินสแตนซ์นี้
  • ข้อมูลอ้างอิง: แสดงการอ้างอิงทุกรายการไปยังออบเจ็กต์ที่ไฮไลต์ในส่วน แท็บอินสแตนซ์

ค้นหาการรั่วไหลของหน่วยความจำ

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

  • อินสแตนซ์ Activity ที่ถูกทำลายแล้วแต่ยังคงมีการอ้างอิง
  • อินสแตนซ์ Fragment ที่ไม่มี FragmentManager ที่ถูกต้องแต่ยังคงมีการอ้างอิง

โปรดทราบว่าตัวกรองอาจให้ผลบวกลวงในสถานการณ์ต่อไปนี้

  • สร้าง Fragment แล้วแต่ยังไม่ได้ใช้งาน
  • ระบบแคช Fragment ไว้ แต่ไม่ได้เป็นส่วนหนึ่งของ FragmentTransaction

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

  • การอ้างอิง Activity, Context, View, Drawable และออบเจ็กต์อื่นๆ อยู่ตลอด ซึ่งอาจมีการอ้างอิงถึงคอนเทนเนอร์ Activity หรือ Context
  • ชั้นเรียนภายในที่ไม่คงที่ เช่น Runnable ซึ่งเก็บ Activity ได้ อินสแตนซ์
  • แคชที่เก็บออบเจ็กต์ไว้นานกว่าที่จำเป็น

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

ทริกเกอร์หน่วยความจำที่รั่วสำหรับการทดสอบ

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

นอกจากนี้ คุณยังทริกเกอร์การรั่วไหลของหน่วยความจำได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  • หมุนอุปกรณ์จากแนวตั้งเป็นแนวนอนและหมุนกลับอีกครั้งหลายๆ ครั้ง เมื่ออยู่ในสถานะกิจกรรมที่ต่างกัน การหมุนอุปกรณ์มักทําให้แอปรั่วออบเจ็กต์ Activity, Context หรือ View เนื่องจากระบบจะสร้าง Activity ขึ้นมาใหม่ และหากแอปของคุณเก็บข้อมูลอ้างอิงออบเจ็กต์ดังกล่าวไว้ที่อื่น ระบบจะเก็บขยะไม่ได้
  • สลับไปมาระหว่างแอปของคุณกับแอปอื่นขณะอยู่ในสถานะกิจกรรมที่แตกต่างกัน เช่น ไปที่หน้าจอหลักแล้วกลับไปที่แอป

ส่งออกและนำเข้าการบันทึกฮีปดัมป์

คุณสามารถ ส่งออกและนำเข้าฮีปดัมป์ จากแท็บการบันทึกที่ผ่านมาในเครื่องมือสร้างโปรไฟล์ 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