Android HandlerThread FD数量优化

背景:

FD泄露通常会造成OOM、ANR甚至Crash。

Android作为Linux系统的一部份,在Linux中“一切都是文件”,从小到一块儿内存区域大到进程、Socket、线程、磁盘文件等都有自身的文件描述符。我们在保证Socket、文件句柄、IO操作不存在泄露的情况下,是否还有其他方面可以优化?

答案是肯定的,不然也不会写这么一篇文章了,那我们今天的主角表面上HandlerThread优化,实际上是通过共享HandlerThread减少FD的创建。

在Android系统中,创建一个HandlerThread通常会创建2个FD,一个是线程的FD,一个是MessageQueue的FD,前者是系统机制,后者是为了epoll队列监控使用。这些 eventfd 由 HandlerThread 创建,每个 HandlerThread 会创建 eventfd 和 epollfd 两个 fd,在 Android 5上甚至会创建三个FD,pipe_in、pipe_out 和 epollfd。

 

原理:

换种思路,让所有的Handler共享同一个HandlerThread,所有的消息都交给同一个Looper去监控,等到执行时间到的时候再转发到其他线程

public class LightHandler extends Handler implements Runnable {
    static final HandlerThread sHandlerThread = new HandlerThread("LightHandlerThread");
    static {
        sHandlerThread.start();
    }
    private AbstractQueue<Message> queue = null;
    private final Thread thread;
    private volatile boolean isQuited = false;

    public LightHandler(String threadName, Callback callback) {
        super(sHandlerThread.getLooper(), callback);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            this.queue = new LinkedTransferQueue<>();
        } else {
            this.queue = new LinkedBlockingQueue<>();
        }
        this.thread = new Thread(Thread.currentThread().getThreadGroup(), this, threadName, 512);
        this.thread.start();
    }
    public LightHandler(String threadName) {
        this(threadName, null);
    }
    @Override
    public void dispatchMessage(Message msg) {
        Message message = Message.obtain(this);
        message.copyFrom(msg);
        queue.offer(message);
    }

    public void doHandleMessage(Message msg) {
        super.dispatchMessage(msg);
    }

    @Override
    public void run() {
        while (!isQuited) {
            Message msg = queue.poll();
            if (msg == null) {
                continue;
            }
            doHandleMessage(msg);
            msg.recycle();
        }
    }

    public boolean isQuited() {
        return isQuited;
    }

    public void quit(){
        isQuited = true;
    }
}

 

评价

优点:

避免了创建更多FD

缺点:

这种依然是有缺点的,主要是同步屏障降对所有Handler开启,当然使用同步屏障的情况实际并不多,理论上也不会有人使用共享ThreadHandler去实现同步屏障。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章