安卓createBitmap OOM时((freeMemory> bitmapSize)及及(nativeFreeHeap<位图大小)) [英] android createBitmap OOM when ((freeMemory > bitmapSize) && (nativeFreeHeap < bitmap size))

查看:536
本文介绍了安卓createBitmap OOM时((freeMemory> bitmapSize)及及(nativeFreeHeap<位图大小))的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Android 2.2系统,下面的程序产生OOM。综上所述,该程序执行以下操作:

  1. 分配,需要本地堆增长接近其最大尺寸的大阵。
  2. 在垃圾收集的数组。
  3. 在尝试创建大小比其余本地免费堆较大的位图。

为什么这与OOM失败?这是因为如果本机堆只会分配内存的位图在内存previously未分配。

输出显示在下面的程序。先谢谢了。

 公共类OomTest延伸活动{
    私有静态最后弦乐OOM_TEST =OomTest;

    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        printDiag();
        Log.i(OOM_TEST,分配大的int数组。);
        INT [] bigIntArray =新INT [11000000]
        printDiag();
        bigIntArray = NULL;
        Log.i(OOM_TEST,垃圾收集。);
        System.gc()的;
        printDiag();
        Log.i(OOM_TEST,创建4兆位位图。);
        点阵位图= Bitmap.createBitmap(1000,1000,Config.ARGB_8888);
        printDiag();
        Log.i(OOM_TEST,完成。);
    }

    私人无效printDiag(){
        Log.i(OOM_TESTmaxMemory:+调用Runtime.getRuntime()maxMemory());
        Log.i(OOM_TEST,totalMemory:
              +调用Runtime.getRuntime()totalMemory())。
        Log.i(OOM_TEST,freeMemory:
              +调用Runtime.getRuntime()freeMemory())。
        Log.i(OOM_TEST,nativeHeapSize:
              + android.os.Debug.getNativeHeapSize());
        Log.i(OOM_TEST,nativeHeapAllocatedSize:
              + android.os.Debug.getNativeHeapAllocatedSize());
        Log.i(OOM_TEST,nativeHeapFreeSize:
              + android.os.Debug.getNativeHeapFreeSize());
    }
}
 

下面是输出:

  I / ActivityManager(2501):开始PROC com.example.android.oomTest的活动
    com.example.android.oomTest / .OomTest:PID = 25242的uid = 10031导报= {1015}
I / OomTest(25242):maxMemory:50331648
I / OomTest(25242):totalMemory:2953200
I / OomTest(25242):freeMemory:479512
I / OomTest(25242):nativeHeapSize:3600384
I / OomTest(25242):nativeHeapAllocatedSize:3585800
I / OomTest(25242):nativeHeapFreeSize:14584
I / OomTest(25242):分配大的int数组。
D / dalvikvm(25242):GC_FOR_MALLOC释放634对象/在过48ms 51344字节
I / dalvikvm堆(25242):成长堆(破片的情况下),以44.573MB为44000016个字节分配
D / dalvikvm(25242):在60ms的GC_FOR_MALLOC释放34的对象/ 1992字节
I / OomTest(25242):maxMemory:50331648
I / OomTest(25242):totalMemory:46997472
I / OomTest(25242):freeMemory:575224
I / OomTest(25242):nativeHeapSize:3600384
I / OomTest(25242):nativeHeapAllocatedSize:3578408
I / OomTest(25242):nativeHeapFreeSize:23560
I / OomTest(25242):垃圾收集。
D / dalvikvm(25242):GC_EXPLICIT在52ms释放65的对象/ 44002952字节
I / OomTest(25242):maxMemory:50331648
I / OomTest(25242):totalMemory:46997472
I / OomTest(25242):freeMemory:44576440
I / OomTest(25242):nativeHeapSize:3600384
I / OomTest(25242):nativeHeapAllocatedSize:3575784
I / OomTest(25242):nativeHeapFreeSize:24600
I / OomTest(25242):创建4兆位位图。
E / dalvikvm堆(25242):400万字节的外部分配太大,此过程。
E / GraphicsJNI(25242):虚拟机不会让我们分配4000000字节
D / AndroidRuntime(25242):关闭虚拟机
W / dalvikvm(25242):主题ID = 1:螺纹退出与未捕获的异常(组= 0x4001d7d0)
E / AndroidRuntime(25242):致命异常:主要
E / AndroidRuntime(25242):java.lang.OutOfMemoryError:位图大小超过VM预算
E / AndroidRuntime(25242):在android.graphics.Bitmap.nativeCreate(本机方法)
E / AndroidRuntime(25242):在android.graphics.Bitmap.createBitmap(Bitmap.java:468)
E / AndroidRuntime(25242):在com.example.android.oomTest.OomTest.onCreate(OomTest.java:26)
 

解决方案

我觉得你深入到无证行为,这里 - 你不能指望任何回答你是在不同的Andr​​oid版本和设备一致

我的猜测是,该系统被授予你的应用程序的最大进程大小。这个过程的大小由Dalvik的堆和本机堆(当然加上一些开销)的。你已经扩大了Dalvik的堆到最大。垃圾收集创造了Dalvik的堆空间,但所有进程的空间分配给了Dalvik的堆,因此无法使用本机堆,所以没有房间,本机堆,以适应位图对象。

我相当肯定在previous这种行为差异(或只是其它?)的Andr​​oid,那里的Dalvik的堆不能扩展超过大约一半的总进程大小限制的版本。

On Android 2.2, the following program produces an OOM. In summary, the program does the following:

  1. Allocates a big array that requires native heap to grow close to its maximum size.
  2. Garbage collects the array.
  3. Attempts to create a bitmap of size larger than the remaining native free heap.

Why does this fail with an OOM? It's as if the native heap will only allocate memory for bitmaps in memory previously unallocated.

The output appears below the program. Thanks in advance.

public class OomTest extends Activity {
    private static final String OOM_TEST = "OomTest";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        printDiag();
        Log.i(OOM_TEST, "Allocating big int array.");
        int[] bigIntArray = new int[11000000];
        printDiag();
        bigIntArray = null;
        Log.i(OOM_TEST, "Garbage collecting.");
        System.gc();
        printDiag();
        Log.i(OOM_TEST, "Creating 4 meg bitmap bitmap.");
        Bitmap bitmap = Bitmap.createBitmap(1000, 1000, Config.ARGB_8888);
        printDiag();        
        Log.i(OOM_TEST, "Done.");
    }

    private void printDiag() {
        Log.i(OOM_TEST, "maxMemory: " + Runtime.getRuntime().maxMemory());
        Log.i(OOM_TEST, "totalMemory: " 
              + Runtime.getRuntime().totalMemory());
        Log.i(OOM_TEST, "freeMemory: " 
              + Runtime.getRuntime().freeMemory());
        Log.i(OOM_TEST, "nativeHeapSize: " 
              + android.os.Debug.getNativeHeapSize());
        Log.i(OOM_TEST, "nativeHeapAllocatedSize: " 
              + android.os.Debug.getNativeHeapAllocatedSize());
        Log.i(OOM_TEST, "nativeHeapFreeSize: " 
              + android.os.Debug.getNativeHeapFreeSize());
    }
}

Here's the output:

I/ActivityManager( 2501): Start proc com.example.android.oomTest for activity
    com.example.android.oomTest/.OomTest: pid=25242 uid=10031 gids={1015}
I/OomTest (25242): maxMemory: 50331648
I/OomTest (25242): totalMemory: 2953200
I/OomTest (25242): freeMemory: 479512
I/OomTest (25242): nativeHeapSize: 3600384
I/OomTest (25242): nativeHeapAllocatedSize: 3585800
I/OomTest (25242): nativeHeapFreeSize: 14584
I/OomTest (25242): Allocating big int array.
D/dalvikvm(25242): GC_FOR_MALLOC freed 634 objects / 51344 bytes in 48ms
I/dalvikvm-heap(25242): Grow heap (frag case) to 44.573MB for 44000016-byte allocation
D/dalvikvm(25242): GC_FOR_MALLOC freed 34 objects / 1992 bytes in 60ms
I/OomTest (25242): maxMemory: 50331648
I/OomTest (25242): totalMemory: 46997472
I/OomTest (25242): freeMemory: 575224
I/OomTest (25242): nativeHeapSize: 3600384
I/OomTest (25242): nativeHeapAllocatedSize: 3578408
I/OomTest (25242): nativeHeapFreeSize: 23560
I/OomTest (25242): Garbage collecting.
D/dalvikvm(25242): GC_EXPLICIT freed 65 objects / 44002952 bytes in 52ms
I/OomTest (25242): maxMemory: 50331648
I/OomTest (25242): totalMemory: 46997472
I/OomTest (25242): freeMemory: 44576440
I/OomTest (25242): nativeHeapSize: 3600384
I/OomTest (25242): nativeHeapAllocatedSize: 3575784
I/OomTest (25242): nativeHeapFreeSize: 24600
I/OomTest (25242): Creating 4 meg bitmap bitmap.
E/dalvikvm-heap(25242): 4000000-byte external allocation too large for this process.
E/GraphicsJNI(25242): VM won't let us allocate 4000000 bytes
D/AndroidRuntime(25242): Shutting down VM
W/dalvikvm(25242): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0)
E/AndroidRuntime(25242): FATAL EXCEPTION: main
E/AndroidRuntime(25242): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
E/AndroidRuntime(25242):        at android.graphics.Bitmap.nativeCreate(Native Method)
E/AndroidRuntime(25242):        at     android.graphics.Bitmap.createBitmap(Bitmap.java:468)
E/AndroidRuntime(25242):        at com.example.android.oomTest.OomTest.onCreate(OomTest.java:26)

解决方案

I think you're deep into undocumented behavior here-- you wouldn't be able to count on any answer you get being consistent across different Android versions or devices.

My guess is that the system is granting your app a maximum process size. The process size consists of the dalvik heap and the native heap (plus some overhead, of course). You've expanded the dalvik heap to the maximum. Garbage collecting created space in the dalvik heap, but all the process's space is allocated to the dalvik heap and is therefore unavailable to the native heap, so there isn't room in the native heap to accomodate the bitmap object.

I'm fairly certain this behavior differed in previous (or just other?) releases of Android, where the dalvik heap could not expand beyond about half of the total process size limit.

这篇关于安卓createBitmap OOM时((freeMemory> bitmapSize)及及(nativeFreeHeap<位图大小))的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆