วิธีเพิ่มขนาดฮีปของแอปพลิเคชัน Android


125

ฉันกำลังเขียนแอปพลิเคชัน Android ซึ่งใช้โมเดล 3 มิติหลายแบบ โมเดลที่มีพื้นผิวดังกล่าวสามารถใช้หน่วยความจำได้มาก ฉันพบว่าผู้ผลิตกำหนดขีด จำกัด ขนาดฮีปที่แอปพลิเคชันสามารถใช้ได้ ตัวอย่างเช่นแท็บเล็ต Samsung Galaxy Tab 8.9 P7310 ของฉันสามารถใช้หน่วยความจำ 64MB

มีวิธีเพิ่มหน่วยความจำขนาดนี้ที่แอปพลิเคชันใช้ได้หรือไม่?

คำตอบ:


210

คุณสามารถใช้android: largeHeap = "true"เพื่อขอขนาดฮีปที่ใหญ่ขึ้นได้ แต่จะใช้ไม่ได้กับอุปกรณ์ Honeycomb รุ่นก่อน ๆ ในอุปกรณ์รุ่นก่อน 2.3 คุณสามารถใช้คลาส VMRuntime ได้ แต่จะใช้ไม่ได้กับ Gingerbread ขึ้นไป

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

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


NDK ดูน่าสนใจ ฉันสามารถใช้ร่วมกับโค้ดของฉันที่เขียนด้วย SDK ได้หรือไม่
cooxie

3
ขึ้นอยู่กับว่าคุณมีรหัสอะไร ฉันไม่ใช่ผู้เชี่ยวชาญกับ NDK และรู้เพียงพื้นฐานเท่านั้น ฉันขอแนะนำให้คุณถามคำถามนี้พร้อมกับคำอธิบายรหัสของคุณในกลุ่ม android-ndk Google หรือโพสต์คำถามใหม่เกี่ยวกับ SO เฉพาะสำหรับเรื่องนี้ด้วยแท็ก android-ndk
Raghav Sood

ฉันสงสัยว่าเราไม่สามารถ "ใช้ Unity3D เป็นคำตอบที่เฉพาะเจาะจงมากขึ้นสำหรับคำถามได้หรือไม่ (" ใช้โมเดล 3 มิติหลายแบบ ") ... ไม่สามารถหาหลักฐานที่ชัดเจนได้อย่างรวดเร็วว่า Unity ใช้ NDK หรือไม่
cregox

3
largeHeap=trueFTW
Luis Artola

2
นักพัฒนาของ android api ตลกมากพวกเขาเหมือนกับว่าคุณต้องการ Heap มากขึ้น? โอเคขอมันสำหรับผู้ที่ต้องการเท่านั้น ... ในขณะที่นักพัฒนาทุกคนกำลังเพิ่มมันเป็นสิ่งแรกที่จะเพิ่มเมื่อแอพเริ่มผลิต :)
AndroidLover

110

มีวิธีเพิ่มหน่วยความจำขนาดนี้ที่แอปพลิเคชันใช้ได้หรือไม่?

โปรแกรมที่ทำงานบน API ระดับ 11 ขึ้นไปสามารถมีandroid:largeHeap="true"ใน<application>องค์ประกอบในที่ประจักษ์เพื่อขอขนาดกองขนาดใหญ่กว่าปกติและgetLargeMemoryClass()บนActivityManagerจะบอกคุณว่าใหญ่ที่กองเป็น อย่างไรก็ตาม:

  1. ใช้ได้กับ API ระดับ 11+ เท่านั้น (เช่น Honeycomb และอื่น ๆ )

  2. ไม่มีการรับประกันว่าฮีปขนาดใหญ่จะมีขนาดใหญ่เพียงใด

  3. ผู้ใช้จะรับรู้คำขอฮีปขนาดใหญ่ของคุณเนื่องจากจะบังคับให้แอปอื่น ๆ ออกจาก RAMจะยุติกระบวนการของแอปอื่น ๆ เพื่อเพิ่ม RAM ของระบบสำหรับฮีปขนาดใหญ่ของคุณ

  4. เนื่องจากข้อ 3 และความจริงที่ว่าฉันคาดว่าandroid:largeHeapจะถูกละเมิดการสนับสนุนสำหรับสิ่งนี้อาจถูกละทิ้งในอนาคตหรือผู้ใช้อาจได้รับคำเตือนเกี่ยวกับเรื่องนี้ในขณะติดตั้ง (เช่นคุณจะต้องขอการอนุญาตพิเศษ )

  5. ปัจจุบันคุณลักษณะนี้ได้รับการบันทึกไว้เล็กน้อย


@CommonsWare ถ้ามีขนาดใหญ่ความร้อนไม่พร้อมใช้งานฉันจะลบวัตถุที่โหลดไว้ก่อนหน้านี้ (เช่นภาพ) ได้อย่างไร
Jeongbebs

@MiguelRivera: สำหรับภาพคุณควรรีไซเคิลความทรงจำ (ดูinBitmapบนBitmapOptions) นอกเหนือจากนั้นให้ลบการอ้างอิงถึงพวกเขาทั้งหมดและในที่สุดก็จะถูกเก็บรวบรวมขยะ
CommonsWare

และคุณแนะนำการตัดสินใจอย่างไร
Gennadiy Ryabkin

@zest: ฉันไม่รู้ว่าคุณหมายถึงอะไรขออภัย
CommonsWare

2
@Eftekhari: ไม่ใช่โดยตรงสำหรับแอปของคุณ มีสิ่งอื่น ๆ อีกอาจทำให้คุณใช้เวลามากขึ้น CPU จะผ่านสิ่งนั้น android:largeHeapแต่รายละเอียดก็จะขึ้นอยู่กับสิ่งที่คุณกำลังทำอยู่กับหน่วยความจำและไม่ได้เชื่อมโยงโดยตรงกับที่มีการร้องขอ อย่างไรก็ตามการขอฮีปขนาดใหญ่อาจเป็นอันตรายต่อประสบการณ์ของผู้ใช้โดยรวมโดยการบังคับให้กระบวนการแอปพลิเคชันอื่นยุติเร็วกว่าที่จำเป็นเป็นอย่างอื่น
CommonsWare

22

คุณไม่สามารถเพิ่มขนาดฮีปแบบไดนามิก

คุณสามารถขอใช้เพิ่มเติมได้โดยใช้android:largeHeap="true"ในรายการ

คุณยังสามารถใช้ได้native memory (NDK & JNI)ดังนั้นคุณจึงข้ามข้อ จำกัด ขนาดฮีปไปได้

นี่คือโพสต์บางส่วนที่ฉันสร้างขึ้นเกี่ยวกับเรื่องนี้:

และนี่คือห้องสมุดที่ฉันสร้างขึ้นเพื่อ:


@ ต่อแอพ จำกัด heap ที่ระดับ java และ native ต่างกันหรือไม่? เช่นตัวอย่างบน s5 devcie 128mb java heap limit และ native สามารถใช้อีก 128 mb?
NitZRobotKoder

ขนาดฮีปคงที่สำหรับแต่ละแอป (ขนาดขึ้นอยู่กับฮาร์ดแวร์และรอม) และควรเท่ากันสำหรับทุกแอป หน่วยความจำเนทีฟเป็นหน่วยความจำจริงของอุปกรณ์ แต่แน่นอนว่ามีข้อ จำกัด เช่นกันเนื่องจากระบบปฏิบัติการบางส่วนใช้
นักพัฒนา Android

ฉันหมายความว่าถ้าแอปของฉันใช้ say native .so + java android Platform + java POJO logic + JavaScript Android มีขนาดฮีปต่างกันในแต่ละระดับหรือไม่?
NitZRobotKoder


@NitZRobotKoder ไม่ขนาดฮีปมีไว้สำหรับโลก Java / Kotlin ซึ่งคุณจะได้รับข้อยกเว้น OOM หากคุณใช้มากเกินไป ส่วนที่เหลือเป็นหน่วยความจำดั้งเดิม
นักพัฒนา Android

6

ใช้กระบวนการที่สอง ประกาศAndroidManifestใหม่Serviceด้วย

android:process=":second"

แลกเปลี่ยนระหว่างกระบวนการแรกและกระบวนการที่สอง BroadcastReceiver


5

ซึ่งสามารถทำได้สองวิธีตามระบบปฏิบัติการ Android ของคุณ

  1. คุณสามารถใช้android:largeHeap="true"ในแท็กแอปพลิเคชันของรายการ Android เพื่อขอขนาดฮีปที่ใหญ่ขึ้น แต่จะใช้ไม่ได้กับอุปกรณ์ Honeycomb รุ่นก่อน ๆ
  2. ในอุปกรณ์รุ่นก่อน 2.3 คุณสามารถใช้คลาส VMRuntime ได้แต่จะใช้ไม่ได้กับ Gingerbread ขึ้นไปดูวิธีการด้านล่าง
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

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

อ้างอิง: http://dwij.co.in/increase-heap-size-of-android-application


4
เห็นได้ชัดว่า <2.3 มีทางและ> 2.3 มีทาง แต่ 2.3 ถูกขัน!
Michael

3

จากสิ่งที่ฉันจำได้ว่าคุณสามารถใช้VMRuntimeคลาสใน Android เวอร์ชันแรก ๆ ได้ แต่ตอนนี้คุณทำไม่ได้แล้ว

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


0

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

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