เครื่องมือสร้างโปรไฟล์หน่วยความจำเป็นคอมโพเนนต์ใน เครื่องมือสร้างโปรไฟล์ Android ที่ จะช่วยระบุการรั่วไหลของหน่วยความจำและการสูญเสียหน่วยความจำที่อาจทำให้เกิดการทำงานติดขัด แอปค้าง และแม้กระทั่งขัดข้องของแอป แสดงกราฟหน่วยความจำของแอปแบบเรียลไทม์ ใช้และให้คุณจับภาพฮีปดัมป์ บังคับให้เก็บรวบรวมขยะ และติดตาม การจัดสรรหน่วยความจำ
หากต้องการเปิดเครื่องมือสร้างโปรไฟล์หน่วยความจำ ให้ทำตามขั้นตอนต่อไปนี้
- คลิกมุมมอง > หน้าต่างเครื่องมือ > เครื่องมือสร้างโปรไฟล์ (หรือจะคลิกโปรไฟล์ก็ได้ ในแถบเครื่องมือ)
- เลือกกระบวนการของอุปกรณ์และแอปที่ต้องการสร้างโปรไฟล์จาก Android แถบเครื่องมือเครื่องมือสร้างโปรไฟล์ หากคุณเชื่อมต่ออุปกรณ์ผ่าน USB แต่ไม่เห็น ในรายการ โปรดตรวจสอบว่าคุณ เปิดใช้การแก้ไขข้อบกพร่อง USB
- คลิกที่ใดก็ได้ในไทม์ไลน์ MEMORY เพื่อเปิดเครื่องมือสร้างโปรไฟล์ Memory
หรือคุณสามารถตรวจสอบหน่วยความจำของแอปจากบรรทัดคำสั่งด้วย dumpsys และ ดูกิจกรรม GC ใน Logcat
เหตุผลที่คุณควรสร้างโปรไฟล์หน่วยความจำของแอป
Android มอบ สภาพแวดล้อมหน่วยความจำที่มีการจัดการ ระบุว่าแอปของคุณไม่ได้ใช้ออบเจ็กต์บางอย่างอีกต่อไป ซึ่งก็คือเครื่องมือเก็บขยะ ปล่อยหน่วยความจำที่ไม่ได้ใช้กลับไปยังฮีป Android ค้นหาอย่างไร หน่วยความจำที่ไม่ได้ใช้กำลังได้รับการปรับปรุงอย่างต่อเนื่อง แต่ในบางขั้นตอนบน Android ทุกรุ่น ระบบจะต้องหยุดโค้ดของคุณชั่วคราว ส่วนใหญ่แล้ว การหยุดชั่วคราว ไม่สามารถรับรู้ได้ อย่างไรก็ตาม หากแอปจัดสรรหน่วยความจำเร็วกว่าระบบ สามารถรวบรวมแอปได้ แอปของคุณอาจล่าช้าในขณะที่ผู้รวบรวมมีเวลาว่างมากพอ เพื่อตอบสนองการจัดสรรของคุณ ความล่าช้าอาจทำให้แอปข้าม และทำให้เห็นการทำงานช้า
แม้ว่าแอปจะไม่แสดงผลช้า แต่หากหน่วยความจำรั่วไหล แอปจะยังรักษาสถานะเดิมไว้ได้ ความทรงจำนั้นแม้จะอยู่ในเบื้องหลัง การทำงานลักษณะนี้อาจทำให้ส่วนที่เหลือทำงานช้าลง ประสิทธิภาพหน่วยความจำของระบบโดยบังคับให้มีการเก็บข้อมูลขยะที่ไม่จำเป็น กิจกรรม ท้ายที่สุดแล้ว ระบบจำเป็นต้องปิดการทำงานของกระบวนการของแอปเพื่อเรียกคืน ความทรงจำ จากนั้นเมื่อผู้ใช้กลับไปที่แอป แอปจะต้องรีสตาร์ทโดยสมบูรณ์
ในการช่วยป้องกันปัญหาเหล่านี้ คุณควรใช้เครื่องมือสร้างโปรไฟล์หน่วยความจำเพื่อดำเนินการ ดังต่อไปนี้:
- มองหารูปแบบการจัดสรรหน่วยความจำที่ไม่พึงประสงค์ในลำดับเวลาที่อาจ อาจทำให้เกิดปัญหาด้านประสิทธิภาพ
- ถ่ายโอนฮีปของ Java เพื่อดูว่าวัตถุใดกำลังใช้หน่วยความจำ ฮีพดัมพ์หลายๆ ตัวในช่วงเวลาที่นานขึ้นจะช่วยระบุ การรั่วไหลของหน่วยความจำ
- บันทึกการจัดสรรหน่วยความจำระหว่างการโต้ตอบของผู้ใช้ตามปกติและรุนแรงไปยัง ระบุตำแหน่งที่โค้ดจัดสรรออบเจ็กต์จำนวนมากเกินไปใน หรือจัดสรรวัตถุที่รั่วไหลได้
สำหรับข้อมูลเกี่ยวกับวิธีจัดโปรแกรมที่อาจลดหน่วยความจำของแอปได้ ให้ใช้ โปรดอ่านหัวข้อจัดการหน่วยความจำของแอป
ภาพรวมเครื่องมือสร้างโปรไฟล์หน่วยความจำ
เมื่อเปิดตัวสร้างโปรไฟล์หน่วยความจำเป็นครั้งแรก คุณจะเห็นลำดับเวลาโดยละเอียดของ การใช้หน่วยความจำของแอปและเข้าถึงเครื่องมือเพื่อบังคับให้เก็บข้อมูลขยะและจับภาพฮีป ดัมพ์ และบันทึกการจัดสรรหน่วยความจำ
ตามที่ระบุไว้ในรูปที่ 1 มุมมองเริ่มต้นสำหรับเครื่องมือสร้างโปรไฟล์หน่วยความจำจะรวมถึง ดังต่อไปนี้:
- ปุ่มสำหรับบังคับเหตุการณ์การเก็บขยะ
-
ปุ่มเพื่อบันทึกฮีปดัมป์
หมายเหตุ: ปุ่มสำหรับบันทึกหน่วยความจำ การจัดสรรจะปรากฏที่ด้านขวาของปุ่มฮีปดัมป์เฉพาะเมื่อ เชื่อมต่อกับอุปกรณ์ที่ใช้ Android 7.1 (API ระดับ 25) หรือต่ำกว่า
- เมนูแบบเลื่อนลงสำหรับระบุความถี่ที่เครื่องมือสร้างโปรไฟล์จะบันทึกความทรงจำ การจัดสรร การเลือกตัวเลือกที่เหมาะสมอาจช่วยคุณ ปรับปรุงประสิทธิภาพของแอปขณะทำโปรไฟล์
- ปุ่มซูมเข้า/ออกจากไทม์ไลน์
- ปุ่มสำหรับข้ามไปยังข้อมูลหน่วยความจำแบบเรียลไทม์
- ไทม์ไลน์ของเหตุการณ์ ซึ่งแสดงสถานะกิจกรรม เหตุการณ์ข้อมูลจากผู้ใช้ และ เหตุการณ์การหมุนหน้าจอ
- ไทม์ไลน์การใช้หน่วยความจำ ซึ่งจะประกอบด้วยข้อมูลต่อไปนี้
- กราฟแบบซ้อนซึ่งแสดงจำนวนหน่วยความจำที่แต่ละหมวดหมู่ใช้หน่วยความจำ ตามที่ระบุโดยแกน y ทางด้านซ้ายและคีย์สี ที่ด้านบน
- เส้นประจะระบุจำนวนออบเจ็กต์ที่จัดสรรตามที่ระบุไว้ ตามแกน Y ทางด้านขวา
- ไอคอนของเหตุการณ์การเก็บรวบรวมขยะแต่ละเหตุการณ์
อย่างไรก็ตาม หากคุณใช้อุปกรณ์ที่ใช้ Android 7.1 หรือต่ำกว่า ข้อมูลการทำโปรไฟล์จะปรากฏโดยค่าเริ่มต้น หากคุณเห็นข้อความ "ขั้นสูง" ทำโปรไฟล์ไม่ได้สำหรับกระบวนการที่เลือก" คุณต้อง เปิดใช้การทำโปรไฟล์ขั้นสูง เพื่อดูข้อมูลต่อไปนี้
- ลำดับเวลาของเหตุการณ์
- จำนวนออบเจ็กต์ที่จัดสรร
- งานกิจกรรมการเก็บขยะ
ใน Android 8.0 ขึ้นไป ระบบจะเปิดใช้การทำโปรไฟล์ขั้นสูงอยู่เสมอเพื่อให้แก้ไขข้อบกพร่องได้ แอป
วิธีนับความทรงจำ
ตัวเลขที่คุณเห็นที่ด้านบนของเครื่องมือสร้างโปรไฟล์หน่วยความจำ (รูปที่ 2) นั้นอิงตาม หน้าหน่วยความจำส่วนตัวทั้งหมดที่แอปของคุณกำหนดไว้ ตาม ระบบ Android จำนวนนี้ไม่รวมหน้าเว็บที่แชร์กับระบบ หรือ แอปอื่นๆ
หมวดหมู่ในจำนวนหน่วยความจำมีดังนี้
- Java: หน่วยความจำจากออบเจ็กต์ที่จัดสรรจากโค้ด Java หรือ Kotlin
เนทีฟ: หน่วยความจำจากออบเจ็กต์ที่จัดสรรจากโค้ด C หรือ C++
แม้ว่าจะไม่ได้ใช้ C++ ในแอป คุณก็อาจเห็นหน่วยความจำของระบบบางส่วน ใช้ที่นี่เนื่องจากเฟรมเวิร์กของ Android ใช้หน่วยความจำในเครื่องในการจัดการ งานต่างๆ ในนามของคุณ เช่น เมื่อจัดการกับชิ้นงานรูปภาพและอื่นๆ กราฟิกของคุณ แม้ว่าโค้ดที่คุณเขียนจะใช้ใน Java หรือ Kotlin ก็ตาม
กราฟิก: หน่วยความจำที่ใช้สำหรับคิวบัฟเฟอร์กราฟิกเพื่อแสดงพิกเซลต่อ รวมถึงพื้นผิว GL, พื้นผิว GL และอื่นๆ (โปรดทราบว่า เป็นหน่วยความจำที่แชร์กับ CPU ไม่ใช่หน่วยความจำ GPU โดยเฉพาะ)
สแต็ก: หน่วยความจำที่ทั้งสแต็กในเครื่องและสแต็ก Java ในแอปใช้ ช่วงเวลานี้ มักเกี่ยวข้องกับจำนวนเทรดที่แอปทำงานอยู่
โค้ด: หน่วยความจำที่แอปใช้สำหรับโค้ดและทรัพยากร เช่น dex ไบต์โค้ด, โค้ด Dex ที่เพิ่มประสิทธิภาพหรือคอมไพล์, ไลบรารี .so และแบบอักษร
อื่นๆ: หน่วยความจำที่แอปของคุณใช้ซึ่งระบบไม่แน่ใจว่าต้องทำอย่างไร จัดหมวดหมู่
จัดสรรแล้ว: จำนวนออบเจ็กต์ Java/Kotlin ที่แอปจัดสรร แต่ไม่นับออบเจ็กต์ที่จัดสรรใน C หรือ C++
การจัดสรรนี้เมื่อเชื่อมต่อกับอุปกรณ์ที่ใช้ Android 7.1 และต่ำกว่า จำนวนจะเริ่มต้นเฉพาะเมื่อเครื่องมือสร้างโปรไฟล์หน่วยความจำเชื่อมต่อกับ ที่กำลังเรียกใช้อยู่ ออบเจ็กต์ที่จัดสรรก่อนที่คุณจะเริ่มทำโปรไฟล์จะไม่ ที่เหมาะสม อย่างไรก็ตาม Android 8.0 ขึ้นไปจะมี เครื่องมือสร้างโปรไฟล์ที่คอยติดตามการจัดสรรทั้งหมด ดังนั้นจำนวนนี้ แสดงจำนวนออบเจ็กต์ Java ทั้งหมดที่รอดำเนินการในแอปของคุณใน Android 8.0 ขึ้นไป
เมื่อเปรียบเทียบกับจำนวนหน่วยความจำจากเครื่องมือ Android Monitor ก่อนหน้านี้ เครื่องมือใหม่ เครื่องมือสร้างโปรไฟล์หน่วยความจำจะบันทึกหน่วยความจำของคุณต่างออกไป จึงอาจทำให้ดูเหมือนว่า และใช้หน่วยความจำมากขึ้น เครื่องมือสร้างโปรไฟล์หน่วยความจำตรวจสอบหมวดหมู่เพิ่มเติมบางหมวดหมู่ ที่จะเพิ่มผลรวม แต่ถ้าคุณสนใจเฉพาะหน่วยความจำฮีปของ Java "Java" ควรคล้ายกับค่าจากเครื่องมือก่อนหน้า แม้ว่าหมายเลข Java อาจไม่ตรงกับที่คุณเห็นใน Android ทุกประการ Monitor บัญชีตัวเลขใหม่สำหรับหน้าหน่วยความจำทางกายภาพทั้งหมดที่ ที่จัดสรรให้กับฮีป Java ของแอปเนื่องจากมีการแยกจาก Zygote อย่างนี้ ให้ข้อมูลที่แม่นยำเกี่ยวกับหน่วยความจำทางกายภาพที่แอปของคุณ ที่กำลังใช้งานอยู่
ดูการจัดสรรหน่วยความจำ
การจัดสรรหน่วยความจำจะแสดงวิธีที่ออบเจ็กต์ Java แต่ละรายการและการอ้างอิง JNI ในไฟล์ จัดสรรหน่วยความจำแล้ว โดยเฉพาะอย่างยิ่ง เครื่องมือสร้างโปรไฟล์หน่วยความจำสามารถแสดง เกี่ยวกับการจัดสรรออบเจ็กต์
- ประเภทของออบเจ็กต์ที่มีการจัดสรรและพื้นที่ที่ใช้
- สแต็กเทรซของการจัดสรรแต่ละรายการ รวมถึงเทรด
- เมื่อมีดีลออบเจ็กต์ (เฉพาะเมื่อใช้อุปกรณ์ที่ใช้ Android 8.0 เท่านั้น หรือสูงกว่า)
หากต้องการบันทึกการจัดสรร Java และ Kotlin ให้เลือก บันทึกการจัดสรร Java / Kotlin จากนั้นเลือกบันทึก ถ้าอุปกรณ์ใช้ Android 8 ขึ้นไป UI ของ Memory Profiler เปลี่ยนเป็นหน้าจอแยกต่างหากที่แสดง บันทึก คุณสามารถโต้ตอบกับไทม์ไลน์แบบย่อเหนือไฟล์บันทึกเสียงได้ (เช่น เพื่อเปลี่ยนช่วงการเลือก) วิธีบันทึกให้เสร็จสมบูรณ์ เลือกหยุด
ใน Android 7.1 และต่ำกว่า เครื่องมือสร้างโปรไฟล์หน่วยความจำจะใช้การจัดสรรแบบเดิม ซึ่งจะแสดงการบันทึกบนไทม์ไลน์จนกว่าคุณจะคลิก หยุด
หลังจากเลือกช่วงเวลาในไทม์ไลน์ (หรือเมื่อบันทึกเสร็จแล้ว เซสชันที่มีอุปกรณ์ที่ใช้ Android 7.1 หรือต่ำกว่า) รายการที่จัดสรรไว้ จะปรากฏขึ้น โดยจัดกลุ่มตามชื่อคลาสและจัดเรียงตาม จำนวนฮีป
หากต้องการตรวจสอบระเบียนการจัดสรร ให้ทำตามขั้นตอนต่อไปนี้
- เรียกดูรายการเพื่อค้นหาออบเจ็กต์ที่มีจำนวนฮีปมากผิดปกติและ
ที่อาจรั่วไหลได้ คลิกชื่อชั้นเรียนเพื่อช่วยค้นหาชั้นเรียนที่รู้จัก
ส่วนหัวคอลัมน์เพื่อจัดเรียงตามลำดับตัวอักษร จากนั้นคลิกชื่อชั้นเรียน
แผงมุมมองอินสแตนซ์จะแสดงทางด้านขวา ซึ่งจะแสดงแต่ละอินสแตนซ์
ดังที่แสดงในรูปที่ 3
- หรือคุณจะหาออบเจ็กต์อย่างรวดเร็วโดยคลิกตัวกรองก็ได้ , หรือกด Control+F (Command+F ใน Mac) และป้อนคลาสหรือแพ็กเกจ ในช่องค้นหา คุณยังสามารถค้นหาตามชื่อเมธอดได้ถ้าคุณเลือก จัดเรียงตาม Calltack จากเมนูแบบเลื่อนลง ถ้าต้องการใช้ปกติ นิพจน์ ให้เลือกกล่องที่อยู่ถัดจาก Regex ทำเครื่องหมายที่ช่องถัดจาก ตรงตามตัวพิมพ์ใหญ่-เล็ก หากคำค้นหาคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่
- คลิกอินสแตนซ์ในแผงมุมมองอินสแตนซ์ แท็บสแต็กการเรียกใช้ ปรากฏด้านล่าง โดยแสดงตำแหน่งที่มีการจัดสรรอินสแตนซ์และเทรด
- ในแท็บ Call Stack ให้คลิกขวาที่บรรทัดใดก็ได้ แล้วเลือก ข้ามไปยังแหล่งที่มาเพื่อเปิดโค้ดดังกล่าวในตัวแก้ไข
คุณสามารถใช้เมนู 2 เมนูเหนือรายการออบเจ็กต์ที่จัดสรรเพื่อเลือก ฮีปเพื่อตรวจสอบและวิธีจัดระเบียบข้อมูล
เลือกฮีปที่จะตรวจสอบจากเมนูด้านซ้าย ดังนี้
- ค่าเริ่มต้นฮีป: เมื่อระบบไม่ได้ระบุฮีป
- image Heap: อิมเมจเปิดเครื่องของระบบ ซึ่งจะมีคลาสที่ ที่โหลดไว้ล่วงหน้าในระหว่างการเปิดเครื่อง เรารับประกันได้ว่าการจัดสรรรายได้นี้จะไม่มีการเคลื่อนย้ายหรือ หายไปเลย
- ฮีป zygote: ฮีปแบบคัดลอกและวางซึ่งกระบวนการของแอปถูกแยกออก ในระบบ Android
- ฮีปแอป: ฮีปหลักที่แอปจัดสรรหน่วยความจำ
- ฮีป JNI: ฮีปที่แสดงตำแหน่งของ Java Native Interface (JNI) การอ้างอิงจะได้รับการจัดสรรและปล่อย
เลือกวิธีการจัดเรียงการจัดสรรจากเมนูทางด้านขวา ดังนี้
- จัดเรียงตามชั้นเรียน: จัดกลุ่มการจัดสรรทั้งหมดตามชื่อชั้นเรียน นี่คือ ค่าเริ่มต้น
- จัดเรียงตามแพ็กเกจ: จัดกลุ่มการจัดสรรทั้งหมดตามชื่อแพ็กเกจ
- จัดเรียงตามการเรียก: จัดกลุ่มการจัดสรรทั้งหมดลงใน สแต็กการเรียกใช้
ปรับปรุงประสิทธิภาพของแอปขณะทำโปรไฟล์
ในการปรับปรุงประสิทธิภาพของแอปขณะทำโปรไฟล์ ตัวอย่างเครื่องมือสร้างโปรไฟล์หน่วยความจำ การจัดสรรหน่วยความจำเป็นระยะโดยค่าเริ่มต้น เมื่อทดสอบในอุปกรณ์ที่ใช้ API ระดับ 26 ขึ้นไป คุณสามารถเปลี่ยนลักษณะการทำงานนี้ได้โดย โดยใช้เมนูแบบเลื่อนลงการติดตามการจัดสรร ตัวเลือกที่มีให้มีดังนี้ ดังต่อไปนี้:
- เต็ม: บันทึกการจัดสรรออบเจ็กต์ทั้งหมดในหน่วยความจำ นี่คือค่าเริ่มต้น พฤติกรรมใน Android Studio 3.2 และรุ่นก่อนหน้า หากคุณมีแอปที่ จัดสรรวัตถุจำนวนมาก คุณอาจเห็นการชะลอตัวที่มองเห็นได้ ขณะทำโปรไฟล์
- สุ่มตัวอย่าง: ตัวอย่างการจัดสรรออบเจ็กต์ในหน่วยความจำในรอบระยะเวลาที่สม่ำเสมอ ช่วงเวลานี้ เป็นตัวเลือกเริ่มต้นและมีผลกระทบน้อยกว่าต่อประสิทธิภาพของแอป การสร้างโปรไฟล์ แอปที่จัดสรรออบเจ็กต์จำนวนมากในระยะเวลาสั้นๆ อาจ ยังคงแสดงการชะลอตัว
- ปิด: หยุดติดตามการจัดสรรหน่วยความจำของแอป
ดูข้อมูลอ้างอิงส่วนกลางของ JNI
Java Native Interface (JNI) เป็นเฟรมเวิร์กที่อนุญาตโค้ด Java และเนทีฟ เพื่อโทรหากัน
การอ้างอิง JNI ได้รับการจัดการด้วยตนเองโดยโค้ดดั้งเดิม ดังนั้นจึงเป็นไปได้สำหรับ ออบเจ็กต์ Java ที่โค้ดแบบเนทีฟใช้จึงคงอยู่เป็นเวลานานเกินไป ออบเจ็กต์บางรายการเปิดอยู่ ฮีป Java อาจเข้าถึงไม่ได้หากมีการทิ้งการอ้างอิง JNI โดยที่ไม่มี ถูกลบอย่างชัดเจนก่อน นอกจากนี้ ยังอาจใช้ JNI ทั่วโลก ขีดจำกัดการอ้างอิง
หากต้องการแก้ปัญหาดังกล่าว ให้ใช้มุมมองฮีป JNI ในเครื่องมือสร้างโปรไฟล์หน่วยความจำเพื่อ เรียกดูการอ้างอิง JNI ทั่วโลกทั้งหมดและกรองตามประเภท Java และการเรียกใช้แบบเนทีฟ สแต็ก ข้อมูลนี้จะช่วยให้คุณค้นหาได้ว่า JNI ทั่วโลกอ้างอิงถึงเมื่อใดและที่ใด ถูกสร้างและลบ
ขณะที่แอปทำงานอยู่ ให้เลือกส่วนหนึ่งของไทม์ไลน์ที่คุณต้องการ ตรวจสอบและเลือก JNI Heap จากเมนูแบบเลื่อนลงเหนือรายการคลาส จากนั้นคุณก็จะตรวจสอบออบเจ็กต์ในฮีปตามปกติแล้วดับเบิลคลิก ในแท็บ สแต็กการเรียกใช้การจัดสรร เพื่อดูตำแหน่งของการอ้างอิง JNI จัดสรรและเผยแพร่ในโค้ดของคุณ ดังที่แสดงในรูปที่ 4
หากต้องการตรวจสอบการจัดสรรหน่วยความจำสำหรับรหัส JNI ของแอป คุณต้องทำให้แอปใช้งานได้ ไปยังอุปกรณ์ที่ใช้ Android 8.0 ขึ้นไป
ดูข้อมูลเพิ่มเติมเกี่ยวกับ JNI ได้ในเคล็ดลับเกี่ยวกับ JNI
เครื่องมือสร้างโปรไฟล์หน่วยความจำของระบบ
Memory Profiler ของ Android Studio มีตัวสร้างโปรไฟล์หน่วยความจำในตัวสำหรับแอป ติดตั้งใช้งานได้ทั้งในอุปกรณ์จริงและอุปกรณ์เสมือนที่ใช้ Android 10 ขึ้นไป
เครื่องมือสร้างโปรไฟล์หน่วยความจำของระบบจะติดตามการจัดสรร/ข้อตกลงกับแบรนด์ สำหรับช่วงเวลาที่เฉพาะเจาะจง และให้ข้อมูลต่อไปนี้
- การจัดสรร: จำนวนออบเจ็กต์ที่จัดสรรผ่าน
malloc()
หรือnew
ในช่วงเวลาที่เลือก - Deallocations: จำนวนออบเจ็กต์ที่มีดีลผ่าน
free()
หรือdelete
ในระหว่างช่วงเวลาที่เลือก - ขนาดการจัดสรร: ขนาดรวมเป็นไบต์ของการจัดสรรทั้งหมดระหว่าง ระยะเวลาที่เลือก
- ขนาดดีล: ขนาดโดยรวมในหน่วยไบต์ของหน่วยความจำที่ว่างทั้งหมด ในช่วงเวลาที่เลือก
- จำนวนรวม: ค่าในคอลัมน์การจัดสรรลบด้วยค่าใน คอลัมน์ตัวแทนจำหน่าย
- ขนาดที่เหลืออยู่: ค่าในคอลัมน์ขนาดการจัดสรรลบด้วยค่า ในคอลัมน์ขนาดของดีล
หากต้องการบันทึกการจัดสรรแบบเนทีฟในอุปกรณ์ที่ใช้ Android 10 ขึ้นไป เลือกบันทึกการจัดสรรแบบเนทีฟ แล้วเลือกบันทึก ไฟล์บันทึกเสียง ดำเนินต่อไปจนกว่าคุณจะคลิกหยุด , หลังจากนั้น UI ของ Memory Profiler จะเปลี่ยนเป็นหน้าจอแยกต่างหาก จะแสดงไฟล์บันทึกในเครื่อง
ใน Android 9 และต่ำกว่า ตัวเลือกบันทึกการจัดสรรแบบเนทีฟจะไม่แสดง พร้อมใช้งาน
โดยค่าเริ่มต้น เครื่องมือสร้างโปรไฟล์หน่วยความจำในเครื่องจะใช้ขนาดการสุ่มตัวอย่าง 32 ไบต์ ดังนี้ มีการจัดสรรหน่วยความจำ 32 ไบต์ ซึ่งจะบันทึกสแนปชอตของหน่วยความจำ ต การเก็บตัวอย่างน้อยลงส่งผลให้ได้สแนปชอตบ่อยขึ้น ช่วยให้เกิดสแนปชอตมากขึ้น ข้อมูลที่ถูกต้องเกี่ยวกับการใช้งานหน่วยความจำ การเก็บตัวอย่างที่ใหญ่ขึ้นจะให้ความถูกต้องแม่นยำน้อยลง แต่จะใช้ทรัพยากรในระบบของคุณน้อยลงและปรับปรุง ประสิทธิภาพขณะบันทึก
วิธีเปลี่ยนขนาดตัวอย่างของเครื่องมือสร้างโปรไฟล์หน่วยความจำของระบบ
- เลือกเรียกใช้ > แก้ไขการกำหนดค่า
- เลือกโมดูลแอปในแผงด้านซ้าย
- คลิกแท็บการทำโปรไฟล์ แล้วป้อนขนาดตัวอย่างในช่องที่มีป้ายกำกับ ช่วงการสุ่มตัวอย่างหน่วยความจำแบบเนทีฟ (ไบต์)
- สร้างและเรียกใช้แอปอีกครั้ง
บันทึกฮีปดัมป์
ฮีปดัมป์แสดงให้เห็นว่าออบเจ็กต์ใดในแอปกำลังใช้หน่วยความจำอยู่ขณะที่คุณ จับภาพฮีปดัมป์ ฮีปดัมป์ โดยเฉพาะหลังจากเซสชันผู้ใช้แบบขยาย สามารถช่วยระบุการรั่วไหลของหน่วยความจำโดยแสดงวัตถุที่ยังอยู่ในหน่วยความจำที่คุณ เชื่อว่าไม่ควรอยู่ที่นั่นอีกต่อไป
หลังจากบันทึกฮีปดัมป์แล้ว คุณจะดูสิ่งต่อไปนี้ได้
- ประเภทออบเจ็กต์ที่แอปจัดสรรไว้และจำนวนออบเจ็กต์แต่ละประเภท
- ออบเจ็กต์แต่ละรายการใช้หน่วยความจำมากเพียงใด
- โดยที่การอ้างอิงไปยังออบเจ็กต์แต่ละรายการในโค้ดของคุณ
- สแต็กการเรียกใช้สำหรับที่มีการจัดสรรออบเจ็กต์ (สแต็กการโทรปัจจุบันคือ ใช้ได้กับฮีพดัมพ์เฉพาะใน Android 7.1 และต่ำกว่าเมื่อคุณจับภาพ ฮีปดัมป์ขณะบันทึกการจัดสรร)
หากต้องการบันทึกฮีปดัมป์ ให้คลิกบันทึกฮีปดัมป์ แล้วเลือกบันทึก ขณะดัมพ์ฮีป จำนวนหน่วยความจำของ Java อาจเพิ่มขึ้นชั่วคราว ซึ่งเป็นเรื่องปกติเนื่องจากฮีปดัมป์เกิดขึ้นในกระบวนการเดียวกันกับแอปของคุณ และต้องใช้หน่วยความจำเพื่อรวบรวมข้อมูล
หลังจากที่เครื่องมือสร้างโปรไฟล์บันทึกฮีปดัมป์เรียบร้อยแล้ว UI ของ Memory Profiler เปลี่ยนเป็นหน้าจอแยกต่างหากที่แสดงฮีปดัมป์
ถ้าคุณต้องการให้ละเอียดขึ้นว่า Dump สร้างขึ้นเมื่อใด
สามารถสร้างฮีปดัมป์ ณ จุดสำคัญในโค้ดของแอปได้ด้วยการเรียกใช้
dumpHprofData()
ในรายชื่อชั้นเรียน คุณจะเห็นข้อมูลต่อไปนี้
- การจัดสรร: จำนวนของการจัดสรรในฮีป
ขนาดเนทีฟ: ปริมาณหน่วยความจำเนทีฟทั้งหมดที่ออบเจ็กต์ประเภทนี้ใช้ (เป็นไบต์) คอลัมน์นี้จะมองเห็นได้สำหรับ Android 7.0 ขึ้นไปเท่านั้น
คุณจะเห็นหน่วยความจำที่นี่สำหรับออบเจ็กต์บางรายการที่จัดสรรใน Java เนื่องจาก Android ใช้หน่วยความจำในเครื่องสำหรับคลาสเฟรมเวิร์กบางคลาส เช่น
Bitmap
ขนาดระดับออบเจ็กต์: จำนวนหน่วยความจำของ Java ทั้งหมดที่ออบเจ็กต์นี้ใช้ type (เป็นไบต์)
ขนาดที่คงไว้: ขนาดหน่วยความจำรวมที่เก็บรักษาไว้เนื่องจากอินสแตนซ์ทั้งหมด ของคลาสนี้ (เป็นไบต์)
คุณสามารถใช้เมนู 2 เมนูเหนือรายการออบเจ็กต์ที่จัดสรรเพื่อเลือก ฮีปดัมป์เพื่อตรวจสอบและวิธีจัดระเบียบข้อมูล
เลือกฮีปที่จะตรวจสอบจากเมนูด้านซ้าย ดังนี้
- ค่าเริ่มต้นฮีป: เมื่อระบบไม่ได้ระบุฮีป
- ฮีปแอป: ฮีปหลักที่แอปจัดสรรหน่วยความจำ
- image Heap: อิมเมจเปิดเครื่องของระบบ ซึ่งจะมีคลาสที่ ที่โหลดไว้ล่วงหน้าในระหว่างการเปิดเครื่อง เรารับประกันได้ว่าการจัดสรรรายได้นี้จะไม่มีการเคลื่อนย้ายหรือ หายไปเลย
- ฮีป zygote: ฮีปแบบคัดลอกและวางซึ่งกระบวนการของแอปถูกแยกออก ในระบบ Android
เลือกวิธีการจัดเรียงการจัดสรรจากเมนูทางด้านขวา ดังนี้
- จัดเรียงตามชั้นเรียน: จัดกลุ่มการจัดสรรทั้งหมดตามชื่อชั้นเรียน นี่คือ ค่าเริ่มต้น
- จัดเรียงตามแพ็กเกจ: จัดกลุ่มการจัดสรรทั้งหมดตามชื่อแพ็กเกจ
- จัดเรียงตามการเรียก: จัดกลุ่มการจัดสรรทั้งหมดลงใน สแต็กการเรียกใช้ ตัวเลือกนี้จะใช้ได้ก็ต่อเมื่อคุณจับภาพฮีปดัมป์ขณะบันทึก การจัดสรร อย่างไรก็ตาม ก็มีออบเจ็กต์ในฮีปที่ ที่จัดสรรไว้ก่อนเริ่มบันทึก เพื่อให้การจัดสรรเหล่านั้นแสดงก่อน แสดงตามชื่อคลาส
รายการจะจัดเรียงตามคอลัมน์ขนาดที่คงไว้โดยค่าเริ่มต้น หากต้องการจัดเรียงตาม ในคอลัมน์อื่น ให้คลิกส่วนหัวของคอลัมน์
คลิกชื่อชั้นเรียนเพื่อเปิดหน้าต่างมุมมองอินสแตนซ์ทางด้านขวา (แสดงในรูปที่ 6) อินสแตนซ์แต่ละรายการที่แสดงประกอบด้วยข้อมูลต่อไปนี้
- ความลึก: จำนวนการรับส่งที่สั้นที่สุดจากรูท GC ไปยังที่เลือก อินสแตนซ์
- ขนาดเนทีฟ: ขนาดของอินสแตนซ์นี้ในหน่วยความจำในเครื่อง คอลัมน์นี้จะมองเห็นได้สำหรับ Android 7.0 ขึ้นไปเท่านั้น
- ขนาดระดับออบเจ็กต์: ขนาดของอินสแตนซ์นี้ในหน่วยความจำ Java
- ขนาดที่คงไว้: ขนาดของหน่วยความจำที่อินสแตนซ์นี้มีผลเหนือกว่า (ตาม แผนผังโดมิเนเตอร์)
หากต้องการตรวจสอบฮีป ให้ทำตามขั้นตอนต่อไปนี้
- เรียกดูรายการเพื่อค้นหาออบเจ็กต์ที่มีจำนวนฮีปมากผิดปกติและ
ที่อาจรั่วไหลได้ คลิกชื่อชั้นเรียนเพื่อช่วยค้นหาชั้นเรียนที่รู้จัก
ส่วนหัวคอลัมน์เพื่อจัดเรียงตามลำดับตัวอักษร จากนั้นคลิกชื่อชั้นเรียน
แผงมุมมองอินสแตนซ์จะแสดงทางด้านขวา ซึ่งจะแสดงแต่ละอินสแตนซ์
ดังที่แสดงในรูปที่ 6
- หรือคุณจะหาออบเจ็กต์อย่างรวดเร็วโดยคลิกตัวกรองก็ได้ , หรือกด Control+F (Command+F ใน Mac) และป้อนคลาสหรือแพ็กเกจ ในช่องค้นหา คุณยังสามารถค้นหาตามชื่อเมธอดได้ถ้าคุณเลือก จัดเรียงตาม Calltack จากเมนูแบบเลื่อนลง ถ้าต้องการใช้ปกติ นิพจน์ ให้เลือกกล่องที่อยู่ถัดจาก Regex ทำเครื่องหมายที่ช่องถัดจาก ตรงตามตัวพิมพ์ใหญ่-เล็ก หากคำค้นหาคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่
- คลิกอินสแตนซ์ในแผงมุมมองอินสแตนซ์ ข้อมูลอ้างอิง
ปรากฏด้านล่าง แสดงการอ้างอิงถึงวัตถุนั้นทั้งหมด
หรือคลิกลูกศรข้างชื่ออินสแตนซ์เพื่อดูช่องทั้งหมด จากนั้นคลิกชื่อช่อง เพื่อดูการอ้างอิงทั้งหมด หากคุณต้องการดูรายละเอียดอินสแตนซ์สำหรับ ในช่อง ให้คลิกขวาที่ช่องนั้นแล้วเลือกไปที่อินสแตนซ์
- ในแท็บข้อมูลอ้างอิง หากคุณระบุข้อมูลอ้างอิงที่อาจ หน่วยความจำรั่วไหล คลิกขวาแล้วเลือกไปที่อินสแตนซ์ การดำเนินการนี้จะเลือก อินสแตนซ์ที่ตรงกันจากฮีปดัมป์ซึ่งแสดงข้อมูลอินสแตนซ์ของตัวเอง
ในฮีปดัมป์ ให้มองหาการรั่วไหลของหน่วยความจำที่เกิดจากสาเหตุต่อไปนี้
- เนื้อหาที่มีการอ้างอิงเป็นระยะเวลานานเกี่ยวกับ
Activity
,Context
,View
,Drawable
และออบเจ็กต์อื่นๆ ที่อาจเก็บ มีการอ้างอิงถึงคอนเทนเนอร์Activity
หรือContext
- ชั้นเรียนภายในที่ไม่คงที่ เช่น
Runnable
ที่ใช้เก็บ อินสแตนซ์Activity
- แคชที่เก็บออบเจ็กต์ไว้นานกว่าที่จำเป็น
บันทึกฮีปดัมป์เป็นไฟล์ HPROF
หลังจากที่บันทึกฮีปดัมป์แล้ว คุณจะดูข้อมูลดังกล่าวได้ในเครื่องมือสร้างโปรไฟล์หน่วยความจำเท่านั้น
ขณะที่เครื่องมือสร้างโปรไฟล์ทำงานอยู่ เมื่อคุณออกจากเซสชันการสร้างโปรไฟล์ คุณจะสูญเสียข้อผิดพลาด
ฮีปดัมป์ ดังนั้นหากต้องการบันทึกเพื่อตรวจทานในภายหลัง ให้ส่งออกฮีปดัมป์
เป็นไฟล์ HPROF ใน Android Studio 3.1 และเวอร์ชันที่ต่ำกว่า ฟังก์ชันส่งออกไฟล์บันทึกไปยังไฟล์
ปุ่ม อยู่ทางด้านซ้ายของแถบเครื่องมือใต้ไทม์ไลน์ ใน
Android Studio 3.2 ขึ้นไป จะมีปุ่มส่งออกฮีปดัมป์ที่
ทางขวาของรายการ Heap Dump แต่ละรายการในแผงเซสชัน ในไฟล์ส่งออกเป็น
ที่ปรากฏขึ้น ให้บันทึกไฟล์ที่มีนามสกุลไฟล์ .hprof
หากต้องการใช้เครื่องมือวิเคราะห์ HPROF อื่นๆ เช่น
jhat
คุณต้องแปลงไฟล์ HPROF จากรูปแบบ Android เป็นรูปแบบ Java SE HPROF
โดยใช้เครื่องมือ hprof-conv
ที่มีอยู่ใน
ไดเรกทอรี android_sdk/platform-tools/
เรียกใช้ hprof-conv
ที่มีอาร์กิวเมนต์ 2 ตัว ได้แก่ ไฟล์ HPROF ต้นฉบับและตำแหน่งที่จะเขียน HPROF ที่แปลงแล้ว
เช่น
hprof-conv heap-original.hprof heap-converted.hprof
นำเข้าไฟล์ฮีปดัมป์
หากต้องการนำเข้าไฟล์ HPROF (.hprof
) ให้คลิกเริ่มเซสชันการทำโปรไฟล์ใหม่
ในช่วง
แผงเซสชัน ให้เลือกโหลดจากไฟล์ แล้วเลือกไฟล์จากไฟล์
เบราว์เซอร์
นอกจากนี้คุณยังนำเข้าไฟล์ HPROF ได้โดยลากไฟล์จากโปรแกรมเรียกดูไฟล์ไปยัง หน้าต่างตัวแก้ไข
การตรวจจับการรั่วไหลในเครื่องมือสร้างโปรไฟล์หน่วยความจำ
เมื่อวิเคราะห์ฮีปดัมป์ในเครื่องมือสร้างโปรไฟล์หน่วยความจำ คุณสามารถกรองการทำโปรไฟล์
ข้อมูลที่ Android Studio คิดว่าอาจบ่งชี้ถึงการรั่วไหลของหน่วยความจำสำหรับ Activity
และ
Fragment
อินสแตนซ์ในแอปของคุณ
ประเภทข้อมูลที่ตัวกรองแสดงมีดังนี้
Activity
อินสแตนซ์ที่ถูกทำลายแล้ว แต่ยังมีการอ้างอิงอยู่Fragment
อินสแตนซ์ที่ไม่มีFragmentManager
ที่ถูกต้องแต่ยังคง ถูกอ้างอิง
ในบางสถานการณ์ เช่น ตัวกรองอาจแสดงผลเป็นเท็จ เชิงบวก:
- สร้าง
Fragment
แล้วแต่ยังไม่ได้ใช้งาน Fragment
ถูกแคชอยู่ แต่ไม่ได้เป็นส่วนหนึ่งของFragmentTransaction
หากต้องการใช้ฟีเจอร์นี้ ให้บันทึกฮีปดัมป์ก่อน หรือนำเข้าไฟล์ฮีปดัมป์ ลงใน Android Studio เพื่อแสดงส่วนย่อยและกิจกรรมที่อาจ หน่วยความจำรั่วไหล เลือกช่องทำเครื่องหมายกิจกรรม/การรั่วไหลของส่วนย่อยในฮีป ช่องดัมพ์ของเครื่องมือสร้างโปรไฟล์หน่วยความจำดังที่แสดงในรูปที่ 7
เทคนิคในการทำโปรไฟล์ความทรงจำ
ขณะที่ใช้เครื่องมือสร้างโปรไฟล์หน่วยความจำ คุณควรใช้โค้ดของแอปอย่างเคร่งครัดและพยายามบังคับใช้ การรั่วไหลของหน่วยความจำ วิธีหนึ่งที่จะกระตุ้นให้เกิดการรั่วไหลของหน่วยความจำในแอปคือการปล่อยให้แอปทำงานเป็นเวลา ก่อนที่จะตรวจสอบฮีป รอยรั่วอาจหยดลงมาที่ด้านบนของ ในฮีปนี้ อย่างไรก็ตาม ยิ่งการรั่วซึมมีขนาดเล็กเท่าไหร่ คุณก็ต้องคอยระวัง เรียกใช้แอปเพื่อดูแอป
ทำให้หน่วยความจำรั่วไหลได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
- หมุนอุปกรณ์จากแนวตั้งเป็นแนวนอนและหมุนกลับอีกครั้งหลายครั้งขณะอยู่ในตำแหน่งที่ต่างกัน
สถานะกิจกรรม การหมุนอุปกรณ์มักทำให้แอปรั่วไหล
Activity
,Context
หรือView
ออบเจ็กต์เนื่องจากระบบ สร้างActivity
ใหม่ และหาก แอปมีการอ้างอิงไปยังหนึ่งในออบเจ็กต์ดังกล่าวที่อื่น แต่ระบบไม่สามารถรวบรวมไฟล์ขยะได้ - สลับไปมาระหว่างแอปของคุณกับอีกแอปหนึ่งขณะอยู่ในสถานะกิจกรรมที่ต่างกัน (ไปยัง หน้าจอหลัก จากนั้นกลับไปที่แอปของคุณ)
เคล็ดลับ: คุณยังสามารถทำตามขั้นตอนข้างต้นโดยใช้ การทดสอบ monkeyrunner