一个安卓小项目
最近做了款Android小应用, 不断读取android的mic数据进行计算, 用于判断当前环境的噪音大小. 但是每运行到十几分钟后就莫名的闪退, 起初以为是程序些的不对导致的错误.
java.lang.OutOfMemoryError: Failed to allocate a 257909772 byte allocation with 4184720 free bytes and 231MB until OOM
起初怀疑代码写的有问题. 仔细检测了下代码似乎写的并无漏洞. 出现这个问题那可能是某个地方出现了内存泄露. 创建的资源没有正常释放. 那如何分析内存溢出呢. Android提供了个很好的分析工具: Profiler
抓取堆栈信息
在Android Studio底部打开Profiler
这里可以查看你的应用具体占用了多少内存. 但是怎么看哪里发生了内测泄露呢? 别着急接着看
首先点击内存占用这块的蓝色区域(如上图第三步)
然后进入记录堆栈信息页面, 点击"Capture heap dump"->Record开始记录堆栈信息
几分钟之后就会自动生成"Heap Dump".
点击旁边的保存图标保存到本地, 后缀为xxx.hprof.
内存分析
分析内存使用情况我们使用的是MAT(MAT下载地址)
导出的hprof文件跟MAT的格式要求不一致, 需要进行转换, 转换方法如下:
在你的SDK/platform-tools目录下运行(例如我本地的是3.hprof文件): hprof-conv 3.hprof 3_3.hprof
打开MAT并导入3_3.hprof文件.
选择"Dominator Tree"->点击"Retained Heap" 按大到小排序排第一的就是造成内测溢出的地方.
看到这里那你也能猜出你程序大概是哪个位置造成内测泄露.
刚看到elementData变量的时候我感觉很奇怪, 它是ArrayList内部的一个数组么, 然道是audioList频繁使用没被GC回收?
最后改造了下写法并手动释放最终修复了这个闪退问题.
参考文章
本文参考文章如下:
https://www.jianshu.com/p/5e7c3fa26cfb
https://blog.csdn.net/mingzaizai_123/article/details/118086390