我正在爲android編寫一個實時遊戲,因此我希望儘可能地儘量減少分配/垃圾回收,正如在android「設計性能」開發者指南中推薦的那樣。Java GC在最小分配後運行非常頻繁
我有一個非常簡單的遊戲,它沒有使用太多內存(<根據hprof堆轉儲堆的2-3%),但是我的併發gc像發條一樣每7秒運行一次,總是釋放大約1MB的內存。我的遊戲已完全暫停,並且沒有做任何有趣的事情,並且運行分配跟蹤器5秒鐘,分配情況非常少。這是打開幾秒鐘後的分配跟蹤器轉儲的全部內容,它佔用的分配不到1kb(主要是達爾維克的東西以及我的鎖的鎖定/解鎖方法)。
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了(或很少)。
我的渲染線程使用GLSurfaceView,它幾乎是暫停時運行的唯一東西,但我只是難住在我的記憶發生的地方。
任何想法表示讚賞。
你在使用任何迭代器嗎?取決於JVM結構的版本,像Collection中的Object可能會產生需要GC的對象。 – RussS 2012-03-10 06:53:51
@RussS我習慣在foreach循環中使用它們,但是我試圖解決這個問題。當我使用它們時,我在分配跟蹤器中看到了數百個ArrayListIterator,但是因爲我刪除了它們,所以我不再看到它們。垃圾收集仍然存在:( – Tim 2012-03-10 08:26:19
)您是否嘗試過在仿真器上運行以查看您是否得到相同的結果? – RussS 2012-03-10 16:41:03