利用自定义线程池解决OOM问题

Camera获取到了byte[]类型的图像数据之后,需要送到so库中,让so库进行相应的处理,并对其处理的结果进行相应的反馈;1s大概有30帧的数据,但是除去一些装载数据的事件,时间就变大了,实际可拿到的帧率就变小了;在此每秒取5帧,每张图片大致1~3M。这大致就是解决这个问题的背景框架。

起因

处理图片时,耗时较长,放在主线程中,会造成卡顿,严重的时候会造成ANR。但是算法库处理时,会依赖于上一帧的数据,所以还是要按照顺序,一帧一帧来处理。
Camera取数据后,立即开启线程处理的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//取数据
mCamera.addCallbackBuffer(new byte[size.width * size.height * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8]);
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (mCallback != null && mCamera != null){
// 处理数据回调
mCallback.onImageAvaliable(data, size.width, size.height);
mCamera.addCallbackBuffer(new byte[size.width * size.height * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8]);
}
}
});

// 开启线程处理部分
ExecutorService pool = Executors.newSingleThreadExecutor();
...
if (isSwitchOn(R.id.fall_detect)) {
pool.execute(new CheckFallAndMoveThread(buf, width, height));
}

这样的话,只允许一个线程执行,多来了的,就排队等待处理,这样便实现了一帧一帧处理,并且还不会阻塞主线程。但是很可惜,这样会造成OOM。

原因

so库处理的时间达到了2s左右(处理的图片没有经过resize),有点长。这样的话,每个需要处理的Runnable都需要一定的空间去存储这个图片,并且此种Executor是Runnable是无限长的,长度会自动变化,空间很快就会用完,也是合情合理。

解决办法

看了一下,默认提供的几种线程池,并不能达到自己的需求,只能自己重新设置一下其中的参数,然后利用这些参数,设置成自己想要的那种模式,即队列长度有限,按顺序执行,然后宁愿少处理几帧,也要避免OOM。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class CalTaskThreadExecutor {
private static final ExecutorService instance = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(2),
new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "SingleTaskPoolThread #" + mCount.getAndIncrement());
}
},
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
Log.e("TAG", "超了");
executor.remove(r);
}
});
public static ExecutorService getInstance(){
return instance;
}
}

十分感谢这篇博客,让我大致明白了其中参数所代表的意义,并按照自己的需求整个相应线程池出来。线程池,这一篇或许就够了

利用自定义线程池解决OOM问题

https://eucham.me/2018/05/20/4ab25bec96b9.html

作者

遇寻

发布于

2018-05-20

更新于

2022-04-21

许可协议

评论