一、出现错误的日志
05-26 21:12:53.131 D/serial_port( 1012): Opening serial port /dev/ttyMT2 with flags 0x2
05-26 21:12:53.131 D/serial_port( 1012): open() fd = 1022
05-26 21:12:53.131 D/serial_port( 1012): Configuring serial port
05-26 21:12:53.131 E/art ( 1012): ashmem_create_region failed for 'indirect ref table': Too many open files
05-26 21:12:53.131 W/art ( 1012): Throwing OutOfMemoryError "Could not allocate JNI Env"
05-26 21:12:53.132 W/DefaultChannelPipeline( 1012): java.lang.OutOfMemoryError: Could not allocate JNI Env
05-26 21:12:53.132 W/DefaultChannelPipeline( 1012): at java.lang.Thread.nativeCreate(Native Method)
05-26 21:12:53.132 W/DefaultChannelPipeline( 1012): at java.lang.Thread.start(Thread.java:730)
05-26 21:12:53.132 W/DefaultChannelPipeline( 1012): at com.azhon.device.MoneyMachine.init(MoneyMachine.java:79)
二、当我们看到这个错误的时候第一反应是不是内存泄露导致程序无法申请到内存而导致的,然而查下来的事实告诉我并不是的…
- 通过模拟软件线上运行情况查看
Profiler
软件占用内存的情况,发现一致持平在50MB左右没有持续的增长;通过dump 内存快照分析也没有发现内存泄露,所以这个问题可以确定不是内存泄露的。
三、盯着错误良久发现上面还有个重要错误信息
05-26 21:12:53.131 E/art ( 1012): ashmem_create_region failed for 'indirect ref table': Too many open files
- 也就是说在软件内打开的文件太多了,导致的内存泄露了,那原因是找到了要怎么去排查解决呢?
四、那在Android中到底能打开最多多少个文件呢,这个就可以通过adb shell来进行查看
- 通过命令
cat /proc/pid/limits
pid也就是当前应用的进程ID
1|Droi:/ # cat /proc/1772/limits
- 从上面图中可以看出
Max open files
为1024个文件
那又怎么查看当前应用打开了哪位文件没有关闭呢?
- 通过命令
ls /proc/pid/fd | wc -l
查看当前打开的文件的总数 - 通过命令
ls -l /proc/pid/fd
查看当前打开的文件
五、通过模拟软件线上运行情况发现是操作串口的文件一直在增加没有被关闭过
- 在结合实际代码,发现在使用完串口后确实没有关闭;导致每次使用在持续的增加。
//在结束使用的地方调用即可
serialPort.close();
到这里这个OOM
异常就解决完成了,简直不要太心酸;自己挖的坑含着泪给它填完了
Code-Porter
代码界的扛把子
我从事多年Android软件开发及物联网方面开发,熟悉Java,Android,前端、数据库开发;对技术要求苛刻、热爱分享、热爱新技术