我正在为Android开发一款游戏,并且与垃圾收集器存在巨大的(并且不可预测的)问题。
在加载的一个阶段,我们分配大约18,000个1616字节数组(一些分块级数据)。有时,但并非总是如此,垃圾收集器将决定在每次分配后运行扫描,慢慢增加堆大小:
06-13 13:51:59.362 16941-17640/com.lp.aeronautical.android D/dalvikvm﹕ GC_FOR_ALLOC freed 0K, 17% free 41923K/50472K, paused 191ms, total 191ms
06-13 13:51:59.362 16941-17640/com.lp.aeronautical.android I/dalvikvm-heap﹕ Grow heap (frag case) to 43.037MB for 1616-byte allocation
06-13 13:51:59.536 16941-17640/com.lp.aeronautical.android D/dalvikvm﹕ GC_FOR_ALLOC freed 0K, 17% free 41926K/50476K, paused 174ms, total 174ms
06-13 13:51:59.536 16941-17640/com.lp.aeronautical.android I/dalvikvm-heap﹕ Grow heap (frag case) to 43.040MB for 1616-byte allocation
06-13 13:51:59.765 16941-17640/com.lp.aeronautical.android D/dalvikvm﹕ GC_FOR_ALLOC freed 0K, 17% free 41931K/50480K, paused 179ms, total 179ms
重复所有18,000次分配。毋庸置疑,这是非常可怕的,并且会让游戏严重失误几分钟。
有没有办法在Android上使用GC?或者至少让它在更大的块中增长? (它通常很好)。
答案 0 :(得分:1)
我最终将所有数组分配转换为使用ByteBuffer.allocateDirect分配的ByteBuffers。这意味着我只进行了18000个非常小的Java堆分配(基本上只是指针),并且所有数组内存都存储在本机内存中。
将大量分配转移到本机内存意味着Dalvik GC不再将分配视为问题。