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去實現同步屏障。

 

 

 

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