如何判断您的活动与内存限制的接近程度?

时间:2010-10-15 15:01:59

标签: java android memory mobile

我正在为Android编写一个图形设计应用程序,用户可以在文档中添加多个图像,其中每个图像都存储为Bitmap对象。每个位图的尺寸大约为800x400像素,并使用ARGB8888像素格式(即每个约1.5Mb)。

我知道大多数第一代Android设备都有16Mb的堆限制,对于较新的手机,此限制为24Mb或更大。我也知道位图内存是在外部分配的,但我很困惑,这是什么意思。

我的问题是:如何在运行时告诉我添加新的Bitmap会让我太接近内存限制?

在有人建议“不要使用那么多内存”之前,我知道我有一个选项是限制用户可以创建的位图数量,以便我知道这个限制对于最基本的Android手机是安全的。但是,我希望内存限制更大的手机能够支持更多的位图和/或更大的位图。

我知道在分配位图时检查OutOfMemory异常。但是,在某些情况下,我只剩下足够的内存来分配一个位图。在此之后,整个应用程序将不稳定,因为即使分配像字符串这样的小东西也可能导致OutOfMemory异常。这是我想避免的。

我不确定如何定义“太接近内存限制”,但我怀疑“不要将超过一半的可用内存分配给位图”这样可以正常工作,因为我存储了其他数据结构在内存中相比之下很小。

2 个答案:

答案 0 :(得分:2)

使用此方法记录已用内存,但我已在

上发布了该内存

Android: out of memory exception in Gallery

请参阅该帖子以获得进一步解释。

public static void logHeap(Class clazz) {
    Double allocated = new Double(Debug.getNativeHeapAllocatedSize())/1048576.0);
    Double available = new Double(Debug.getNativeHeapSize())/1048576.0);
    Double free = new Double(Debug.getNativeHeapFreeSize())/1048576.0);
    DecimalFormat df = new DecimalFormat();
    df.setMaximumFractionDigits(2);
    df.setMinimumFractionDigits(2);

    Log.d(APP, "debug. =================================");
    Log.d(APP, "debug.heap native: allocated " + df.format(allocated) + "MB of " + df.format(available) + "MB (" + df.format(free) + "MB free) in [" + clazz.getName().replaceAll("com.myapp.android.","") + "]");
    Log.d(APP, "debug.memory: allocated: " + df.format(new Double(Runtime.getRuntime().totalMemory()/1048576.0)) + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576.0))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576.0)) +"MB free)");
    System.gc();
    System.gc();

    // don't need to add the following lines, it's just an app specific handling in my app        
    if (allocated>=(new Double(Runtime.getRuntime().maxMemory())/1048576.0)-MEMORY_BUFFER_LIMIT_FOR_RESTART)) {
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}

答案 1 :(得分:0)

也许重写onLowMemory类会让你做你想做的事。

@Override
public void onLowMemory() {
    super.onLowMemory();
    //What you want to do
}