java - Android 上的 VaSTLy Overzealous GC

标签 java android garbage-collection

我正在为 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 吗?或者至少让它以更大的 block 增长堆? (通常情况下效果很好)。

最佳答案

我最终将所有数组分配转换为使用 ByteBuffer.allocateDirect 分配的 ByteBuffer。这意味着我只进行了 18000 个非常小的 Java 堆分配(基本上只是指针),并且所有数组内存都存储在 native 内存中。

将大量分配移至 native 内存意味着 Dalvik GC 不再将分配视为问题。

关于java - Android 上的 VaSTLy Overzealous GC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30821939/

相关文章:

java 空闲内存使用情况

java - 不使用 session 变量从servlet调用jsp页面

具有基于时间更新的 Android 自定义 View

c# - 垃圾收集和 GCHandle.Alloc

java - 具有延迟加载业务标识符的 Hibernate/JPA equals() 和 hashCode()

java - 从 OpenCV 的 LBP 实现中提取特征向量

Android - 生物识别信息是否与设备上的特定用户或一般设备相关联?

android - Android Studio Gradle错误 “Multiple dex files define…”

javascript - JS 垃圾回收

java - 如何使用objdump反汇编OpenJDK(bin/java)?