แอพ Android มีปัญหาหน่วยความจำไม่เพียงพอ - ลองทุกอย่างแล้วก็ยังขาดทุน


87

ฉันใช้เวลา 4 วันเต็มในการพยายามทุกอย่างเท่าที่ทำได้เพื่อหาว่าหน่วยความจำรั่วในแอปที่ฉันกำลังพัฒนา แต่สิ่งต่างๆก็หยุดลงเมื่อนานมาแล้ว

แอปที่ฉันกำลังพัฒนานั้นมีลักษณะทางสังคมดังนั้นให้คิดว่าโปรไฟล์กิจกรรม (P) และแสดงรายการกิจกรรมพร้อมข้อมูล - ตัวอย่างเช่นป้าย (B) คุณสามารถกระโดดจากโปรไฟล์ไปยังรายการป้ายไปยังโปรไฟล์อื่น ๆ ไปยังรายการอื่น ๆ ฯลฯ

ลองนึกภาพการไหลเช่นนี้ P1 -> B1 -> P2 -> B2 -> P3 -> B3 เป็นต้นเพื่อความสอดคล้องฉันกำลังโหลดโปรไฟล์และป้ายของผู้ใช้คนเดียวกันดังนั้นหน้า P แต่ละหน้าจึงเหมือนกันและเป็นเช่นนั้น แต่ละหน้า B

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

หลังจากทำทุกอย่างเท่าที่จะนึกได้ว่าทำไมฉันถึงมีหน่วยความจำไม่เพียงพอฉันก็คิดอะไรไม่ออก สิ่งที่ฉันไม่เข้าใจคือทำไม Android ถึงไม่ฆ่า P1, B1 และอื่น ๆ หากหน่วยความจำหมดเมื่อโหลดและขัดข้องแทน ฉันคาดว่ากิจกรรมก่อนหน้านี้จะตายและฟื้นคืนชีพถ้าฉันกลับไปหาพวกเขาผ่าน onCreate () และ onRestoreInstanceState ()

นับประสาสิ่งนี้ - แม้ว่าฉันจะทำ P1 -> B1 -> ย้อนกลับ -> B1 -> ย้อนกลับ -> B1 ฉันก็ยังได้รับความผิดพลาด สิ่งนี้บ่งบอกถึงการรั่วไหลของหน่วยความจำบางประเภทแม้หลังจากทิ้ง hprof และใช้ MAT และ JProfiler ฉันไม่สามารถระบุได้

ฉันได้ปิดใช้งานการโหลดรูปภาพจากเว็บ (และเพิ่มข้อมูลการทดสอบที่โหลดเพื่อชดเชยและทำการทดสอบอย่างยุติธรรม) และตรวจสอบให้แน่ใจว่าแคชรูปภาพใช้ SoftReferences จริงๆแล้ว Android พยายามเพิ่ม SoftReferences บางส่วนที่มี แต่ก่อนที่หน่วยความจำจะล่ม

หน้าป้ายรับข้อมูลจากเว็บโหลดลงในอาร์เรย์ของ EntityData จาก BaseAdapter และป้อนข้อมูลไปยัง ListView (จริงๆแล้วฉันใช้ MergeAdapter ที่ยอดเยี่ยมของCommonsWareแต่ในกิจกรรม Badge นี้มีอะแดปเตอร์เพียง 1 ตัวเท่านั้น แต่ฉัน ต้องการพูดถึงข้อเท็จจริงนี้ไม่ทางใดก็ทางหนึ่ง)

ฉันได้ตรวจสอบรหัสแล้วและไม่พบสิ่งที่จะรั่วไหล ฉันล้างและลบล้างทุกอย่างที่ฉันพบและแม้แต่ System.gc () ซ้ายและขวา แต่แอพก็ยังขัดข้อง

ฉันยังไม่เข้าใจว่าทำไมกิจกรรมที่ไม่ได้ใช้งานที่อยู่ในกองซ้อนจึงไม่ได้รับการเก็บเกี่ยวและฉันก็ชอบที่จะคิดออกจริงๆ

ณ จุดนี้ฉันกำลังมองหาคำแนะนำคำแนะนำวิธีแก้ปัญหา ... อะไรก็ได้ที่ช่วยได้

ขอขอบคุณ.


ดังนั้นหากฉันเปิด 15 กิจกรรมในช่วง 20 วินาทีที่ผ่านมา (ผู้ใช้กำลังดำเนินการอย่างรวดเร็ว) อาจเป็นปัญหาได้หรือไม่? ฉันควรเพิ่มโค้ดบรรทัดใดเพื่อล้างกิจกรรมหลังจากที่ได้แสดงแล้ว ฉันได้รับoutOfMemoryข้อผิดพลาด ขอบคุณ!
Ruchir Baronia

คำตอบ:


109

ฉันยังไม่เข้าใจว่าทำไมกิจกรรมที่ไม่ได้ใช้งานที่อยู่ในกองซ้อนจึงไม่ได้รับการเก็บเกี่ยวและฉันก็ชอบที่จะคิดออกจริงๆ

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

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

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

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

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

ตอนนี้เท่าที่คุณขัดข้องในโฟลว์ที่คุณกดย้อนกลับไปที่กิจกรรมกดย้อนกลับไปที่กิจกรรมอื่น ฯลฯ และไม่เคยมีสแต็คที่ลึกใช่แล้วคุณแค่มีการรั่วไหล โพสต์บล็อกนี้อธิบายถึงวิธีการแก้ปัญหาการรั่วไหล: http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html


47
ในการป้องกันของ OP นี่ไม่ใช่สิ่งที่เอกสารแนะนำ การอ้างถึงdeveloper.android.com/guide/topics/fundamentals/… "(เมื่อหยุดกิจกรรม) ผู้ใช้จะมองไม่เห็นอีกต่อไปและระบบสามารถฆ่าได้เมื่อจำเป็นต้องใช้หน่วยความจำที่อื่น" "ถ้ากิจกรรมถูกหยุดชั่วคราวหรือหยุดทำงานระบบสามารถนำออกจากหน่วยความจำได้ ... โดยขอให้ดำเนินการให้เสร็จสิ้น (เรียกวิธีการเสร็จสิ้น ())" "(เรียก onDestroy ()) เนื่องจากระบบกำลังทำลายอินสแตนซ์นี้ชั่วคราว กิจกรรมเพื่อประหยัดพื้นที่ "
CommonsWare

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

6
ฉันคิดว่าฉันได้วางสิ่งนี้ไว้ที่นี่แล้ว แต่ฉันโพสต์คำขอให้อัปเดตเอกสารสำหรับสิ่งนี้: code.google.com/p/android/issues/detail?id=21552
Justin Breitfeller

15
มันเป็นปี 2013 และเอกสารเพิ่งนำเสนอจุดเท็จให้ชัดเจนยิ่งขึ้น: developer.android.com/training/basics/activity-lifecycle/… , "เมื่อกิจกรรมของคุณหยุดทำงานระบบอาจทำลายอินสแตนซ์หากจำเป็นต้องกู้คืน หน่วยความจำระบบในกรณี EXTREME ระบบอาจฆ่ากระบวนการแอปของคุณ "
kaay

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

22

เคล็ดลับบางประการ:

  1. ตรวจสอบให้แน่ใจว่าคุณไม่มีบริบทกิจกรรมรั่วไหล

  2. ตรวจสอบให้แน่ใจว่าคุณไม่ได้เก็บข้อมูลอ้างอิงไว้ในบิตแมป ทำความสะอาด ImageView ทั้งหมดของคุณในกิจกรรม # onStop ดังนี้:

    Drawable d = imageView.getDrawable();  
    if (d != null) d.setCallback(null);  
    imageView.setImageDrawable(null);  
    imageView.setBackgroundDrawable(null);
    
  3. รีไซเคิลบิตแมปหากคุณไม่ต้องการอีกต่อไป

  4. หากคุณใช้แคชหน่วยความจำเช่น memory-lru ตรวจสอบให้แน่ใจว่าไม่ได้ใช้หน่วยความจำมากนัก

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

  6. ใน Android 4.2 มีข้อผิดพลาด (stackoverflow # 13754876) ที่มีการเร่งด้วยฮาร์ดแวร์ดังนั้นหากคุณใช้hardwareAccelerated=trueในไฟล์ Manifest หน่วยความจำจะรั่ว GLES20DisplayList- เก็บข้อมูลอ้างอิงไว้แม้ว่าคุณจะทำตามขั้นตอนที่ (2) และไม่มีใครอ้างอิงถึงบิตแมปนี้ ที่นี่คุณต้องการ:

    a) ปิดใช้งานการเร่งฮาร์ดแวร์สำหรับ api 16/17;
    หรือ
    b) ถอดมุมมองที่ถือบิตแมป

  7. สำหรับ Android 3+ คุณสามารถลองใช้android:largeHeap="true"ในAndroidManifestไฟล์. แต่จะไม่แก้ปัญหาความจำของคุณเพียงแค่เลื่อนออกไป

  8. หากคุณต้องการเช่นการนำทางที่ไม่มีที่สิ้นสุดดังนั้น Fragments - ควรเป็นทางเลือกของคุณ ดังนั้นคุณจะมี 1 กิจกรรมซึ่งจะสลับไปมาระหว่างชิ้นส่วน วิธีนี้จะช่วยแก้ปัญหาหน่วยความจำบางอย่างเช่นข้อ 4

  9. ใช้ Memory Analyzer เพื่อค้นหาสาเหตุของการรั่วไหลของหน่วยความจำ
    นี่คือวิดีโอที่ดีมากจากGoogle I / O 2011: การจัดการหน่วยความจำสำหรับ Android Apps
    หากคุณจัดการกับบิตแมปสิ่งนี้ควรอ่าน: การแสดงบิตแมปอย่างมีประสิทธิภาพ


ดังนั้นหากฉันเปิด 15 กิจกรรมในช่วง 20 วินาทีที่ผ่านมา (ผู้ใช้กำลังดำเนินการอย่างรวดเร็ว) อาจเป็นปัญหาได้หรือไม่? ฉันควรเพิ่มโค้ดบรรทัดใดเพื่อล้างกิจกรรมหลังจากที่ได้แสดงแล้ว ฉันได้รับoutOfMemoryข้อผิดพลาด ขอบคุณ!
Ruchir Baronia

4

บิตแมปมักเป็นตัวการสำหรับข้อผิดพลาดของหน่วยความจำบน Android ดังนั้นจึงเป็นพื้นที่ที่ดีในการตรวจสอบอีกครั้ง


ดังนั้นหากฉันเปิด 15 กิจกรรมในช่วง 20 วินาทีที่ผ่านมา (ผู้ใช้กำลังดำเนินการอย่างรวดเร็ว) อาจเป็นปัญหาได้หรือไม่? ฉันควรเพิ่มโค้ดบรรทัดใดเพื่อล้างกิจกรรมหลังจากที่ได้แสดงแล้ว ฉันได้รับoutOfMemoryข้อผิดพลาด ขอบคุณ!
Ruchir Baronia

2

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

เราสามารถทำซ้ำข้อผิดพลาดนี้บนอุปกรณ์อื่น ๆ ได้เช่นกัน ฉันพบพฤติกรรมแปลก ๆ ของอุปกรณ์ Android บางอย่างขึ้นอยู่กับ ROM และ / หรือผู้ผลิตฮาร์ดแวร์


ฉันสามารถทำซ้ำสิ่งนี้บน Droid ที่ใช้ CM7 โดยตั้งค่าฮีปสูงสุดเป็น 16MB ซึ่งเป็นค่าเดียวกับที่ฉันทดสอบกับโปรแกรมจำลอง
Artem Russakovskii

คุณอาจจะเข้าสู่บางสิ่งบางอย่าง เมื่อกิจกรรมที่ 2 เริ่มขึ้นกิจกรรมที่ 1 จะทำ onPause-> onStop หรือเพียงแค่ onPause? เนื่องจากฉันกำลังพิมพ์ทั้งหมดในการโทรรอบอายุการใช้งาน ******* และฉันเห็น onPause -> onCreate โดยไม่ต้อง onStop และหนึ่งในการทิ้งข้อผิดพลาดจริง ๆ กล่าวว่าบางอย่างเช่น onPause = true หรือ onStop = false สำหรับกิจกรรม 3 อย่างที่มันกำลังฆ่า
Artem Russakovskii

ควรเรียกใช้ OnStop เมื่อกิจกรรมออกจากหน้าจอ แต่อาจไม่เป็นเช่นนั้นหากระบบเรียกคืนก่อนกำหนด
dten

ไม่ได้รับการเรียกคืนเนื่องจากฉันไม่เห็น onCreate และ onRestoreInstanceState เรียกว่าถ้าฉันคลิกย้อนกลับ
Artem Russakovskii

ตามวงจรชีวิตที่อาจไม่ถูกเรียกตรวจสอบคำตอบของฉันที่มีลิงก์ไปยังบล็อกของนักพัฒนาซอฟต์แวร์อย่างเป็นทางการมันเป็นไปได้มากกว่าที่คุณจะส่งบิตแมปไปรอบ ๆ
dten

2

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

ฉันเจอปัญหาตรงกันข้ามในขณะที่กลับมาพร้อมกับบริการนั่นคือสิ่งที่ทำให้ฉันเกิดความคิดนี้: มีบางอย่างที่ทำให้กิจกรรมของคุณอยู่ในลำดับความสำคัญของกระบวนการสูงเพื่อที่จะไม่ต้องอยู่ภายใต้ GC ของระบบเช่น การอ้างอิง (@Tim) หรือวนซ้ำ (@Alvaro) ลูปไม่จำเป็นต้องเป็นรายการที่ไม่มีที่สิ้นสุดหรือใช้งานได้ยาวนานเพียงแค่สิ่งที่ทำงานมากเช่นวิธีการวนซ้ำหรือการวนซ้ำแบบเรียงซ้อน (หรือบางอย่างตามเส้นเหล่านั้น)

แก้ไข:ตามที่ฉันเข้าใจแล้ว Android จะเรียก onPause และ onStop ตามที่ต้องการโดยอัตโนมัติ วิธีการส่วนใหญ่มีไว้สำหรับคุณในการแก้ไขเพื่อให้คุณสามารถดูแลสิ่งที่คุณต้องการก่อนที่กระบวนการโฮสติ้งจะหยุดลง (ตัวแปรการบันทึกสถานะการบันทึกด้วยตนเอง ฯลฯ ) แต่โปรดทราบว่ามีการระบุไว้อย่างชัดเจนว่า onStop (พร้อมกับ onDestroy) อาจไม่ถูกเรียกในทุกกรณี นอกจากนี้หากกระบวนการโฮสต์ยังโฮสต์กิจกรรมบริการ ฯลฯ ที่มีสถานะ "Forground" หรือ "Visible" ระบบปฏิบัติการอาจไม่ได้มองไปที่การหยุดกระบวนการ / เธรด ตัวอย่างเช่นกิจกรรมและบริการทั้งสองได้รับการสนับสนุนในกระบวนการเดียวกันและบริการจะส่งคืนSTART_STICKYจากonStartCommand()กระบวนการนี้จะมีสถานะที่มองเห็นได้โดยอัตโนมัติ นั่นอาจเป็นกุญแจสำคัญที่นี่ลองประกาศ proc ใหม่สำหรับกิจกรรมและดูว่ามีการเปลี่ยนแปลงอะไรหรือไม่ ลองเพิ่มบรรทัดนี้ในการประกาศกิจกรรมของคุณในรายการ Manifest เป็น: android:process=":proc2"แล้วเรียกใช้การทดสอบอีกครั้งหากกิจกรรมของคุณใช้กระบวนการร่วมกับสิ่งอื่นใด ความคิดในที่นี้ก็คือหากคุณทำความสะอาดกิจกรรมของคุณและค่อนข้างแน่ใจว่าปัญหาไม่ใช่กิจกรรมของคุณสิ่งอื่นคือปัญหาและถึงเวลาที่จะต้องค้นหาสิ่งนั้น

นอกจากนี้ฉันจำไม่ได้ว่าเคยเห็นที่ไหน (แม้ว่าจะเห็นในเอกสาร Android) แต่ฉันจำบางอย่างเกี่ยวกับการPendingIntentอ้างอิงกิจกรรมอาจทำให้กิจกรรมทำงานในลักษณะนี้ได้

นี่คือลิงค์สำหรับonStartCommand()เพจที่มีข้อมูลเชิงลึกเกี่ยวกับกระบวนการที่ไม่ฆ่า


ตามลิงค์ที่คุณให้ไว้ (ขอบคุณ) กิจกรรมอาจถูกฆ่าได้หากมีการเรียก onStop แต่ในกรณีของฉันฉันคิดว่ามีบางอย่างขัดขวางไม่ให้ onStop ทำงาน ฉันจะตรวจสอบสาเหตุอย่างแน่นอน อย่างไรก็ตามยังกล่าวอีกว่ากิจกรรมที่มีเฉพาะ onPause สามารถถูกฆ่าได้เช่นกันซึ่งไม่ได้เกิดขึ้นในกรณีของฉัน (ฉันเห็น onPause ได้รับการเรียก แต่ไม่ใช่ onStop)
Artem Russakovskii

1

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


1

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


ใช่ฉันได้ยินและอ่านหลายครั้งแล้ว แต่ฉันมีปัญหาในการตรึงมันลง ถ้าเพียง แต่ฉันสามารถหาวิธีติดตามสิ่งเหล่านั้นได้อย่างน่าเชื่อถือ
Artem Russakovskii

1
ในกรณีของฉันสิ่งนี้แปลเป็นตัวแปรใด ๆ ในระดับคลาสที่กำหนดให้เท่ากับบริบท (เช่น Class1.variable = getContext ();) โดยทั่วไปการแทนที่ทุกการใช้งาน "บริบท" ในแอปของฉันด้วยการเรียกใหม่ไปที่ "getContext" หรือสิ่งที่คล้ายกันช่วยแก้ปัญหาหน่วยความจำที่ใหญ่ที่สุดของฉันได้ แต่ของฉันไม่มั่นคงและไม่แน่นอนไม่สามารถคาดเดาได้เหมือนในกรณีของคุณดังนั้นอาจมีบางอย่างที่แตกต่างออกไป
D2TheC

1

ลองส่ง getApplicationContext () ไปยังอะไรก็ได้ที่ต้องการ Context คุณอาจมีตัวแปรส่วนกลางที่มีการอ้างอิงถึงกิจกรรมของคุณและป้องกันไม่ให้ถูกเก็บรวบรวมขยะ


1

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

คำตอบของ Dianne Hackborn และการสนทนาในภายหลังของเรา (ขอบคุณ CommonsWare) ช่วยชี้แจงบางสิ่งที่ฉันสับสนดังนั้นขอขอบคุณสำหรับสิ่งนั้น


ฉันรู้ว่านี่เป็นหัวข้อเก่า แต่ดูเหมือนว่าจะพบกระทู้นี้จากการค้นหาหลายครั้ง ฉันต้องการเชื่อมโยงบทช่วยสอนที่ยอดเยี่ยมที่ฉันได้เรียนรู้มากมายจากที่คุณสามารถพบได้ที่นี่: developer.android.com/training/displaying-bitmaps/index.html
Codeversed

0

ฉันพบปัญหาเดียวกันกับคุณ ฉันกำลังทำงานกับแอพส่งข้อความโต้ตอบแบบทันทีสำหรับผู้ติดต่อคนเดียวกันเป็นไปได้ที่จะเริ่ม ProfileActivity ใน ChatActivity และในทางกลับกัน ฉันเพิ่งเพิ่มสตริงพิเศษในจุดประสงค์เพื่อเริ่มกิจกรรมอื่นโดยใช้ข้อมูลประเภทคลาสของกิจกรรมเริ่มต้นและรหัสผู้ใช้ ตัวอย่างเช่น ProfileActivity เริ่มต้น ChatActivity จากนั้นใน ChatActivity.onCreate ฉันทำเครื่องหมายประเภทคลาสผู้เรียกใช้ "ProfileActivity" และรหัสผู้ใช้ถ้าจะเริ่มกิจกรรมฉันจะตรวจสอบว่าเป็น "ProfileActivity" สำหรับผู้ใช้หรือไม่ . ในกรณีนี้ให้เรียก 'finish ()' และกลับไปที่ ProfileActivity เดิมแทนที่จะสร้างใหม่ ความจำรั่วเป็นอีกสิ่งหนึ่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.