在Android 2.2上,以下程序生成OOM。总之,该计划执行以下操作:
为什么这会因OOM而失败?就像本机堆只为先前未分配的内存中的位图分配内存一样。
输出显示在程序下方。提前谢谢。
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());
}
}
这是输出:
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)
答案 0 :(得分:1)
我认为你已经深入到了无证件行为 - 你无法指望在不同的Android版本或设备上保持一致的任何答案。
我的猜测是系统正在授予您的应用最大进程大小。进程大小由dalvik堆和本机堆组成(当然还有一些开销)。您已将dalvik堆扩展到最大值。垃圾收集dalvik堆中创建的空间,但所有进程的空间都分配给dalvik堆,因此本机堆不可用,因此本机堆中没有空间来容纳位图对象。
我相当肯定这个行为在以前的(或其他?)版本的Android中有所不同,其中dalvik堆无法扩展到超过总流程大小限制的一半。