在Android开发中,官方建议开发者应努力减少内存的使用,采用回收和复用的方法,而不是通过增大内存来解决内存问题。当内存过大时,每次垃圾回收(gc)的时间也会变长,可能导致性能下降。
largeHeap具体分配大小
largeHeap属性本身并不直接指定一个具体的内存大小。实际可以看做是一个用于向系统请求为应用进程分配更大的堆内存空间标志。具体能为虚拟机分配多大的堆内存,取决于当前设备的配置和系统的内存管理策略。
在Android设备中,每个应用都会有一个内存最大值的限制。在应用的manifest文件中为某个activity或整个应用设置了largeHeap="true"后,这个应用或activity可以尝试使用比默认限制更大的堆内存。“更大”的堆内存具体有多大,并不是固定的,受到设备总内存、其他应用和系统服务的内存需求,以及Android版本和厂商定制等因素的影响。
获取当前应用可以使用的最大堆内存大小方法:
//如果largeHeap属性被设置为true,将返回一个比默认情况下更大的值。
Runtime.getRuntime().maxMemory()
//获得应用正常情况下内存的大小
ActivityManager.getMemoryClass();
//获得开启largeHeap最大的内存大小
ActivityManager.getLargeMemoryClass();
在/system/build.prop文件中,可以找到与内存管理相关的设置,如dalvik.vm.heapsize和dalvik.vm.heapgrowthlimit。定义了应用进程堆内存的默认大小和增长限制。
通过adb shell查看:
cat /system/build.prop
图片
- 「dalvik.vm.heapstartsize=8m」 相当于Java虚拟机的-Xms配置,用来设置堆内存的初始大小。
- 「dalvik.vm.heapgrowthlimit=192m」 相当于虚拟机的-XX:HeapGrowthLimit配置,用来设置一个标准的应用的最大堆内存大小。一个标准的应用就是没有使用android:largeHeap属性的应用。
- 「dalvik.vm.heapsize=512m」 相当于虚拟机的-Xmx配置,设置了使用android:largeHeap的应用的最大堆内存大小。
- 「dalvik.vm.heaptargetutilizatinotallow=0.75」 相当于虚拟机的-XX:HeapTargetUtilization,用来设置当前理想的堆内存利用率。取值位于0与1之间,当GC进行完垃圾回收之后,Dalvik的堆内存会进行相应的调整,通常结果是当前存活的对象的大小与堆内存大小做除法,得到的值为这个选项的设置,即这里的0.75。注意,这只是一个参考值,Dalvik虚拟机也可以忽略此设置。
- 「dalvik.vm.heapminfree=2m与dalvik.vm.heapmaxfree=8m」 前者对应的是-XX:HeapMinFree配置,用来设置单次堆内存调整的最小值。后者对应的是-XX:HeapMaxFree配置,用来设置单次堆内存调整的最大值。通常情况下,还需要结合上面的-XX:HeapTargetUtilization的值,才能确定内存调整时,需要调整的大小。
使用largeHeap属性弊端
largeHeap会增加应用的内存使用。虽然可以帮助解决某些OutOfMemoryError(OOM)的问题,但也可能导致系统垃圾回收(GC)的时间变长。垃圾回收是Android系统用于清理不再使用的内存的过程,当堆内存变得更大时,这个过程可能需要更长的时间。可能导致应用在执行某些任务时变得卡顿,尤其是在进行复杂的UI操作时,如RecyclerView的滑动可能会变得异常缓慢。
过度使用largeHeap可能会对整个系统的性能产生负面影响。如果每个应用都请求更多的内存,那么系统可用的总内存就会减少。可能导致系统需要更频繁地进行内存管理操作,如内存交换或杀死后台进程,以释放足够的内存给前台应用。不仅可能影响前台应用的性能,还可能影响用户的多任务体验。
依赖largeHeap来解决内存问题并不是一种长期或可持续的解决方案。更好的做法应该是优化应用的内存使用,确保应用能够高效地管理其内存资源。
largeHeap属性并不能保证应用一定能够获得更多的内存。即使设置了largeHeap="true",系统仍然会根据设备的总内存、其他应用的内存需求以及系统的内存管理策略来决定实际分配给应用的内存大小。