Android

记一次android特殊的OOM经历

2019-07-07  本文已影响0人  老衲法号能吃

最近新版本上线,测试同学新写了个变态的测试脚本去测试我们应用的性能,结果遇到了一个非常诡异的现象,当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 //查看详细的句柄信息

需要一点一点的注释代码,排查产生句柄的代码,缩小范围,然后查看如何导致的内存泄漏。

上一篇下一篇

猜你喜欢

热点阅读