这件事情就说来话长了。

记得那是一年前,我被安排去做一个OpenGL相关的任务,就是做一个动画,但是这个动画比较重要,是主要交互界面的背景,我们一般称这个动画为”粒子系统“。

动画被搞出来了,也优化了好久。但是一直有一个问题,就是用一段时间后就会卡死,整个界面都不能动了。包括我在内,大家都认为是粒子系统的问题。但是又苦于没有找到可以优化的点,这件事就一直被搁置。

那时候就有一个奇怪的现象,就是我的这套”粒子系统“,用在另一个项目上就没有什么问题,我当时也很费解,感觉可能不是粒子系统导致的界面卡死,而是其他原因。但是有说不清楚这个”其他原因“是什么,所以还是我的问题。

终于!哈哈,请允许我笑下。我发现”粒子系统崩溃“时有个奇怪的现象,就是整个app都无法进行数据库的操作,通过进一步的观察好像是整个app都无法进行文件读取操作,而且读文件时有个异常:EMFILE (Too many open files)。当时我就想:会不会是这个异常导致我的粒子系统崩溃,而不是我的粒子系统导致的这个异常。接着,我逐渐证实了我的想法。
接着我开始接触一系列的概念,”文件描述符“、”ulimit“、”lsof“,紧接着我看到了一篇博客论File Descriptor泄漏如何导致Crash?看完这个,我更加确信自己的想法。没错,这个困扰了我一年的bug,我终于逮到你了!!!

# 查看进程ID
ps | grep 包名

# lsof(list open files)是一个列出当前系统打开文件的工具

# 这个命令可以查看App打开的文件
lsof | grep 包名 | grep 进程ID

# 这个命令可以查看App打开的文件数,默认的最大文件数为1024, busybox是一个工具集
lsof | grep 包名 | grep 进程ID | busybox wc -l

一般造成此类的原因是文件open后没有close,或者使用了FileDescriptor没有close。

通过以上排查发现是我们用的Spotify player的问题,我们用的那个版本为1.0.0-beta12,通过lsof观察,只要spotify播放,打开的文件数就一直在增加。今天我通过升级sdk解决了这个问题。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

分享几则Android面试题 上一篇
2017的下半年 下一篇