我正在为android编写一个实时游戏,因此我想尽可能地减少分配/垃圾回收,这是androids“为性能而设计”开发人员指南中的建议。
我有一个非常简单的游戏,它不使用太多的内存(根据hprof堆转储,小于2-3%的堆),但是我的并发gc每7秒就像时钟一样运行,总是释放大约1MB的内存。我的游戏完全暂停了,没有做任何有趣的事情,并且运行分配跟踪器5秒,显示很少的分配。这是打开几秒钟后的整个分配跟踪器转储,它看起来只占不到1kb的分配(主要是dalvik的东西和我的lock/unlock方法)。
19 24 byte[] 5 dalvik.system.NativeStart run
18 12 java.lang.Integer 5 java.lang.Integer valueOf
17 24 org.apache.harmony.dalvik.ddmc.Chunk 5 org.apache.harmony.dalvik.ddmc.DdmServer dispatch
16 17 byte[] 5 android.ddm.DdmHandleHeap handleREAQ
15 24 org.apache.harmony.dalvik.ddmc.Chunk 5 android.ddm.DdmHandleHeap handleREAQ
14 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
13 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
12 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
11 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
10 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
9 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
8 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
7 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
6 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
5 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
4 28 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node 10 java.util.concurrent.locks.AbstractQueuedSynchronizer addWaiter
3 24 byte[] 5 dalvik.system.NativeStart run
2 12 java.lang.Integer 5 java.lang.Integer valueOf
1 24 org.apache.harmony.dalvik.ddmc.Chunk 5 org.apache.harmony.dalvik.ddmc.DdmServer dispatch 然而,尽管如此,我仍然每隔几秒钟就会看到大约1MB的收集:
03-09 21:41:56.665: D/dalvikvm(4210): GC_CONCURRENT freed 934K, 58% free 3069K/7175K, external 2847K/3550K, paused 3ms+2ms
03-09 21:42:03.685: D/dalvikvm(4210): GC_CONCURRENT freed 937K, 58% free 3069K/7175K, external 2847K/3550K, paused 3ms+1ms
03-09 21:42:10.705: D/dalvikvm(4210): GC_CONCURRENT freed 937K, 58% free 3069K/7175K, external 2847K/3550K, paused 5ms+2ms
03-09 21:42:17.715: D/dalvikvm(4210): GC_CONCURRENT freed 934K, 58% free 3069K/7175K, external 2847K/3550K, paused 3ms+1ms
03-09 21:42:24.725: D/dalvikvm(4210): GC_CONCURRENT freed 934K, 58% free 3069K/7175K, external 2847K/3550K, paused 2ms+3ms我知道时间不多,但如果我能避免的话,我不想让10毫秒的时间从我的帧中被随机偷走。我的问题是,如果我在分配跟踪器中看不到任何东西,那么在短短几秒钟内分配这么多内存是什么原因呢?我不认为这是手机背景上的任何东西,因为一旦我退出游戏,我就再也看不到GC了(或者很少看到GC)。
我的渲染线程使用GLSurfaceView,它几乎是唯一在暂停时运行的东西,但我只是被我的内存去向难住了。
任何想法都是值得感谢的。
发布于 2012-03-11 02:54:58
好了,我找到漏洞了。原来我不必要地在一个浮动数组上运行了大约每帧50次的克隆,但真正让我感到困惑的是,这并没有出现在分配跟踪器中。
更多的研究向我展示了这个thread,它似乎声称有一个android bug,其中array.clone()操作没有显示在分配跟踪器中。
令人沮丧的是,我花了这么长时间才找到它,但至少现在我每秒只能收集<1kb。
https://stackoverflow.com/questions/9644271
复制相似问题