在bugly的后台,某个应用宝的渠道包上,出现java 层的OOM。
Java 堆内存oom 有两种情况:
- 其一是java new 对象占用的堆内存达到最大上限maxMemory,超过384m或者512M;
- 其二是没有足够大小的连续地址空间,这种情况一般是进程中存在大量的内存碎片导致的,其堆栈信息会比第一种OOM堆栈多出一段信息:failed due to fragmentation (required continguous free “<< required_bytes << “ bytes for a new buffer where largest contiguous free ” << largest_continuous_free_pages << “ bytes)”; 其详细代码在art/runtime/gc/allocator/rosalloc.cc中。
从报错的日志来看,bugly捕捉的java 堆内存的OOM 属于第二种,没有可足够大小的连续空间。
现象
查看java 调用栈:
发现Java 堆内存只剩下4.8M ,却要生成一个17M的bitmap ,因此直接抛出OOM。在android 8.0 以下,bitmap所占内存是在java heap 。
查看下设备信息,全是8.0以下设备:
分析过程
为了搞清楚,是哪些对象将java heap 内存耗尽,或者存在内存泄漏情况。
接着,编译游戏的应用宝渠道debug包,获取到当前中内存快照hrop:
发现存在20多个17M的Bitmap(28*17m=476M) ,当前设备是android 12,因此在bitmap 内存在native heap 中,没有发生oom现象。若是发生在android 8.0以下设备,这些直接将挤爆java heap(迷你世界的java heap 512M),发生oom。
接着是调用发现是腾讯某个sdk 中 帧动画 AnimationDrawable 导致的问题;
最终,将该问题反馈给合作方(应用宝技术),腾讯 应用宝的sdk 会热更修复该问题。
接入外来sdk时,尽量检测其demo上的内存、线程、fd 情况,避免带来不可控的风险。