最近新版本上线,测试同学新写了个变态的测试脚本去测试我们应用的性能,结果遇到了一个非常诡异的现象,当app运行一定的次数之后,就会崩溃,由于我们是系统应用,崩溃之后,系统会重新拉起APP。所以该问题一直没有暴露出来。直到最近。
日志
oom的相关日志
06-17 22:25:48.366 12937 12937 W System.err: java.lang.OutOfMemoryError: Could not allocate JNI Env
06-17 22:25:48.366 12937 12937 W System.err: at java.lang.Thread.nativeCreate(Native Method)
06-17 22:25:48.366 12937 12937 W System.err: at java.lang.Thread.start(Thread.java:730)
...
引发oom的相关日志
06-11 06:15:20.981 13253 31854 F Looper : Could not create epoll instance: Too many open files
先解释第二条日志的原因,linux系统对于每个进程能够操作的文件句柄数量有一个上限,通常是1024,如果超过了这个上限,就会崩溃。我们平时的操作,比如文件,数据库的读写,bitmap的加载,以至于socket的打开关闭,so文件,dex文件的读取,都会直接影响这个句柄数量的增减。如下
package.name 15713 system mem REG 259,22 806688 934478 /data/data/ package.name/app_SGLib/libsgmainso-5.1.96.so
package.name 15713 system mem unknown /dev/ashmem/dalvik-CompilerMetadata (deleted)
package.name 15713 system mem REG 259,20 10952 2308 /system/lib64/libscreencapture_jni.so
package.name 15713 system mem unknown /dev/ashmem/dalvik-indirect ref table (deleted)
package.name 15713 system mem REG 259,22 221824 1310962 /data/app/ package.name-vfKvuMdB9mVCsGbB4t_mCg==/oat/arm64/base.odex
package.name 15713 system mem REG 259,22 11836592 1310965 /data/app package.name-vfKvuMdB9mVCsGbB4t_mCg==/oat/arm64/base.vdex
package.name 15713 system 154u 0000 0,10 0t0 6783 anon_inode:[eventfd]
package.name 15713 system 155u 0000 0,10 0t0 6783 anon_inode:[eventpoll]
package.name 15713 system 156w REG 259,22 3241 934842 /data/data/package.name/cache/image_manager_disk_cache/journal
package.name 15713 system 91u REG 259,22 28672 942294 /data/data/com.hisense.smartimages/databases/report.db
package.name 15713 system 92u sock 0t0 192613 socket:[192613]
package.name 15713 system 93u sock 0t0 193069 socket:[193069]
解决思路
OOM的原因很简单,就是内部类持有了外部类的引用未及时释放,导致了每次都会新增内存,但是深入的分析,就是文件句柄超出了数量限制。
既然是打开了太多的文件,则意味着某个地方的文件资源或者内存未释放,导致了如上两个问题,接下来就是问题排查,如果想要排查文件增减,可以通过如下命令
adb shell
ps -A //查看对应应用的pid
cd/proc/pid/fd //进入指定目录下
ls -l|wc -l //查看句柄数增减情况
lsof -p pid //查看详细的句柄信息
需要一点一点的注释代码,排查产生句柄的代码,缩小范围,然后查看如何导致的内存泄漏。
网友评论