Android内存优化(3)-Android系统堆内存限制浅析

Android的Dalvik虚拟机,和Java虚拟机有很多类似的特点,比如它们的对象都是创建在堆上的。

但是,虚拟机本身对堆内存的大小是有限制的。如果在堆内存已经用满的时候,再想创建一个新的对象的话,就会抛出“Out of Memory”非捕捉异常,程序直接崩溃退出。所以,程序本身必须合理的控制好自己的内存使用,防止超出上限。

不过,每一个Android的设备,其最大对内存的大小上限都是不一样的。笔者就碰到过一个程序在某些手机上能顺利运行,但在另外的几款上就会崩溃的情况。并且,并不一定一个Android设备物理内存大,其Dalvik虚拟机最大堆内存就一定会被设置的很大。

因此,如果你的程序要加载很大的资源到内存中,耗费很大的堆内存,并且还要保证这个程序可以在所有设备上运行,最好的做法是根据不同设备的最大堆内存上限值,加载不一样的资源,或做不一样的处理。


下面,就简单介绍一下Android系统中关于堆内存大小限制的几个重要参数,以及其含义,还有如何得到具体的数值。

1)起始堆内存大小

Dalvik虚拟机启动的时候,会先分配一块初始的堆内存给虚拟机使用。

可以通过下面的命令查看当前Android设备上设置的起始堆内存大小的具体数值:

getprop dalvik.vm.heapstartsize

这个只是初始值,实际Dalvik虚拟机的堆内存是可以在这个初始值上增长的,所以一般程序并不关心它的具体大小。

但这个值的大小会影响到应用的流畅性和系统整体物理内存的消耗,是设备生产厂商需要考虑的。这个数值越小,则系统内存消耗的越慢,但可能影响到程序的反应速度;相反,如果这个数值越大,则程序的相应速度会较快,但系统内存消耗的就会很快。

2)受控情况下的最大堆内存大小

前面也提到了,Dalvik虚拟机的堆是可以增长的,但这个增长也不是无限制的。

在正常情况下,它有一个上限值,如果Dalvik虚拟机实际堆内存使用大小超过了这个限定值,则程序会直接抛出“Out of Memory”非检测异常。

可以通过下面的命令获得当前Android设备上的这个限制值:

getprop dalvik.vm.heapgrowthlimit

也可以在程序中,通过以下代码片段获得:

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int normalHeap = activityManager.getMemoryClass();

这个数值非常关键,是系统给每一个程序的最大堆上限。可以在程序中,判断这个数值的大小来做不一样的处理,从而最大程度实现通用化。

3)不受控情况下的最大堆内存大小

如果你的程序实在是需要非常大的堆内存,前面的那个限制值已经不能满足你的要求的话,还可以向系统申请更多的内存。

可以在程序的AndroidManefest.xml文件中的Application标签上,加入android:largeHeap="true"属性来向系统说明,本程序要很大的内存,请多给我点:



在这种情况下,系统会允许给这个应用更大的堆内存空间,可以超出前面的那个限制。但同样,也不会你想要多大就给多大,因此还有一个限制值,只不过这个限制值比普通应用的更大。

可以通过下面的命令获得当前Android设备上的这个限制值:

getprop dalvik.vm.heapsize

或者也可以在程序中,通过下面的代码片段获得:

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int largeHeap = activityManager.getLargeMemoryClass();

你可能感兴趣的:(Android内存优化(3)-Android系统堆内存限制浅析)