Android應(yīng)用開發(fā)中l(wèi)argeHeap屬性的妙用與潛在風(fēng)險
largeHeap是Android開發(fā)中的一個屬性,主要作用是向系統(tǒng)請求為App進程的虛擬機分配更大的堆內(nèi)存空間。在manifest文件的application節(jié)點或activity節(jié)點中使用。largeHeap屬性設(shè)置為true時,應(yīng)用可以使用更大的堆內(nèi)存。具體能為虛擬機分配多大的堆內(nèi)存,取決于當(dāng)前設(shè)備的相關(guān)配置,由dalvik.vm.heapsize后面的配置大小限制。
在Android開發(fā)中,官方建議開發(fā)者應(yīng)努力減少內(nèi)存的使用,采用回收和復(fù)用的方法,而不是通過增大內(nèi)存來解決內(nèi)存問題。當(dāng)內(nèi)存過大時,每次垃圾回收(gc)的時間也會變長,可能導(dǎo)致性能下降。
largeHeap具體分配大小
largeHeap屬性本身并不直接指定一個具體的內(nèi)存大小。實際可以看做是一個用于向系統(tǒng)請求為應(yīng)用進程分配更大的堆內(nèi)存空間標(biāo)志。具體能為虛擬機分配多大的堆內(nèi)存,取決于當(dāng)前設(shè)備的配置和系統(tǒng)的內(nèi)存管理策略。
在Android設(shè)備中,每個應(yīng)用都會有一個內(nèi)存最大值的限制。在應(yīng)用的manifest文件中為某個activity或整個應(yīng)用設(shè)置了largeHeap="true"后,這個應(yīng)用或activity可以嘗試使用比默認(rèn)限制更大的堆內(nèi)存。“更大”的堆內(nèi)存具體有多大,并不是固定的,受到設(shè)備總內(nèi)存、其他應(yīng)用和系統(tǒng)服務(wù)的內(nèi)存需求,以及Android版本和廠商定制等因素的影響。
獲取當(dāng)前應(yīng)用可以使用的最大堆內(nèi)存大小方法:
//如果largeHeap屬性被設(shè)置為true,將返回一個比默認(rèn)情況下更大的值。
Runtime.getRuntime().maxMemory()
//獲得應(yīng)用正常情況下內(nèi)存的大小
ActivityManager.getMemoryClass();
//獲得開啟largeHeap最大的內(nèi)存大小
ActivityManager.getLargeMemoryClass();在/system/build.prop文件中,可以找到與內(nèi)存管理相關(guān)的設(shè)置,如dalvik.vm.heapsize和dalvik.vm.heapgrowthlimit。定義了應(yīng)用進程堆內(nèi)存的默認(rèn)大小和增長限制。
通過adb shell查看:
cat /system/build.prop
圖片
- 「dalvik.vm.heapstartsize=8m」 相當(dāng)于Java虛擬機的-Xms配置,用來設(shè)置堆內(nèi)存的初始大小。
- 「dalvik.vm.heapgrowthlimit=192m」 相當(dāng)于虛擬機的-XX:HeapGrowthLimit配置,用來設(shè)置一個標(biāo)準(zhǔn)的應(yīng)用的最大堆內(nèi)存大小。一個標(biāo)準(zhǔn)的應(yīng)用就是沒有使用android:largeHeap屬性的應(yīng)用。
- 「dalvik.vm.heapsize=512m」 相當(dāng)于虛擬機的-Xmx配置,設(shè)置了使用android:largeHeap的應(yīng)用的最大堆內(nèi)存大小。
- 「dalvik.vm.heaptargetutilizatinotallow=0.75」 相當(dāng)于虛擬機的-XX:HeapTargetUtilization,用來設(shè)置當(dāng)前理想的堆內(nèi)存利用率。取值位于0與1之間,當(dāng)GC進行完垃圾回收之后,Dalvik的堆內(nèi)存會進行相應(yīng)的調(diào)整,通常結(jié)果是當(dāng)前存活的對象的大小與堆內(nèi)存大小做除法,得到的值為這個選項的設(shè)置,即這里的0.75。注意,這只是一個參考值,Dalvik虛擬機也可以忽略此設(shè)置。
- 「dalvik.vm.heapminfree=2m與dalvik.vm.heapmaxfree=8m」 前者對應(yīng)的是-XX:HeapMinFree配置,用來設(shè)置單次堆內(nèi)存調(diào)整的最小值。后者對應(yīng)的是-XX:HeapMaxFree配置,用來設(shè)置單次堆內(nèi)存調(diào)整的最大值。通常情況下,還需要結(jié)合上面的-XX:HeapTargetUtilization的值,才能確定內(nèi)存調(diào)整時,需要調(diào)整的大小。
使用largeHeap屬性弊端
largeHeap會增加應(yīng)用的內(nèi)存使用。雖然可以幫助解決某些OutOfMemoryError(OOM)的問題,但也可能導(dǎo)致系統(tǒng)垃圾回收(GC)的時間變長。垃圾回收是Android系統(tǒng)用于清理不再使用的內(nèi)存的過程,當(dāng)堆內(nèi)存變得更大時,這個過程可能需要更長的時間。可能導(dǎo)致應(yīng)用在執(zhí)行某些任務(wù)時變得卡頓,尤其是在進行復(fù)雜的UI操作時,如RecyclerView的滑動可能會變得異常緩慢。
過度使用largeHeap可能會對整個系統(tǒng)的性能產(chǎn)生負(fù)面影響。如果每個應(yīng)用都請求更多的內(nèi)存,那么系統(tǒng)可用的總內(nèi)存就會減少。可能導(dǎo)致系統(tǒng)需要更頻繁地進行內(nèi)存管理操作,如內(nèi)存交換或殺死后臺進程,以釋放足夠的內(nèi)存給前臺應(yīng)用。不僅可能影響前臺應(yīng)用的性能,還可能影響用戶的多任務(wù)體驗。
依賴largeHeap來解決內(nèi)存問題并不是一種長期或可持續(xù)的解決方案。更好的做法應(yīng)該是優(yōu)化應(yīng)用的內(nèi)存使用,確保應(yīng)用能夠高效地管理其內(nèi)存資源。
largeHeap屬性并不能保證應(yīng)用一定能夠獲得更多的內(nèi)存。即使設(shè)置了largeHeap="true",系統(tǒng)仍然會根據(jù)設(shè)備的總內(nèi)存、其他應(yīng)用的內(nèi)存需求以及系統(tǒng)的內(nèi)存管理策略來決定實際分配給應(yīng)用的內(nèi)存大小。




























