gpt4 book ai didi

Java GC 在最小分配后运行非常频繁

转载 作者:太空狗 更新时间:2023-10-29 12:53:16 24 4
gpt4 key购买 nike

我正在为 android 编写一个实时游戏,因此我想按照 android“为性能而设计”开发人员指南中的建议尽可能减少分配/垃圾收集。

我有一个非常简单的游戏,它没有使用太多内存(根据 hprof 堆转储,<2-3% 的堆),但我的并发 gc 每 7 秒运行一次,总是释放大约 1MB 的内存。我的游戏完全暂停并且没有做任何有趣的事情,并且运行分配跟踪器 5 秒显示分配很少。这是打开几秒钟后分配跟踪器转储的全部内容,看起来占不到 1kb 的分配(主要是 dalvik 的东西和我的锁的锁定/解锁方法)。

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,这几乎是唯一在暂停时运行的东西,但我只是对我的内存去向感到困惑。

如有任何想法,我们将不胜感激。

最佳答案

好的,我找到了漏洞。事实证明,我在 float 组上不必要地每帧运行 clone 大约 50 次,但真正让我失望的是这并没有出现在分配跟踪器中。

更多的研究向我展示了这个 thread ,这似乎声称存在一个 android 错误,其中 array.clone() 操作未显示在分配跟踪器中。

很沮丧我花了这么长时间才找到它,但至少现在我每秒只收集 <1kb。

关于Java GC 在最小分配后运行非常频繁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9644271/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com