Sean's Note: 9月 2013

2013年9月30日 星期一

Symbol path for Windows debuggers

一般指定本地端的 symbol 檔路徑的指令如下,
.sympath c:\MySymbols
而 Debugger 查詢 symbol 檔的順序為:
  1. c:\MySymbols\symbols\dll
  2. c:\MySymbols\dll
  3. c:\MySymbols
  4. Current Directory
  5. Current Directory\dll

如果電腦有連接網路最有效率的方法就是直接連 Symbol Server,

srv*symbolstore

Microsoft's symbol store:

.sympath srv*http://msdl.microsoft.com/download/symbols

建議加上 Cahce:

.sympath cache*;srv*http://msdl.microsoft.com/download/symbols

cache* 是指把 symbol 檔存到 default 的本地端,下次就不用載一次。

2013年9月16日 星期一

About AsyncTask

AsyncTask 隨著 Android SDK 的更新,也改變了幾次設定。在 Android 1.5(CUPCAKE) 中,
AsyncTask 是 Single Thread,一個 task 接著一個 task 執行;從 Android 1.6(DONUT) 一直到
Android 2.3(GINGERBREAD),AsyncTask 變成了 Multi-Thread,當 tasks 剛好等於 5 個時,
最多就可以同時執行 5 個 threads (CORE_POOL_SIZE=5) 來完成 tasks,如果又多 1 個 task,
就會放到 queue 裡,這個 queue 的大小為 10,直到 queue 放不下時,才會在建立一個 thread
來處理新進的 task,最多可有 128 (MAXIMUM_POOL_SIZE) 個 threads 同時處理 tasks,而
tasks 最多可有 128+10=138 個,超過時會發生 java.util.concurrent.RejectedExecutionException
以上所提到的定義值,可在 AsyncTask.java 的原始碼中看到:
    // Source code of Android 4.2.1 r.1.2
    public abstract class AsyncTask <Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";

    private static final int CORE_POOL_SIZE = 5;
    private static final int MAXIMUM_POOL_SIZE = 128;
    private static final int KEEP_ALIVE = 1;
    ...

    private static final BlockingQueue<runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<runnable>(10);

    ...
Android 4.4 之後,CORE_POOL_SIZE 改為 CPU_COUNT+1,MAXIMUM_POOL_SIZE 改為 CPU_COUNT*2+1,queue 的大小改為 128,所以 threads 變少了(猜想應該是為了效能的關係),queue 變大了。
    // Source code of Android 4.4 r1 
    // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/os/AsyncTask.java#AsyncTask 
    public abstract class AsyncTask <Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE = 1;
    ...

    private static final BlockingQueue<runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<runnable>(128);

    ...

從 Android 3.0(HONEYCOMB) 之後又改回了 Single Thread。Single Thread 版本的 tasks 最多
大小則取決於記憶體,因為是使用 ArrayDeque 來存放 tasks:

private static class SerialExecutor implements Executor {
    final ArrayDeque<runnable> mTasks = new ArrayDeque<runnable>();
    Runnable mActive;

    public synchronized void execute(final Runnable r) {
        mTasks.offer(new Runnable() {
        ...

另外,想要使用之前 Multi-Thread 的版本就要呼叫
executeOnExecutor(THREAD_POOL_EXECUTOR, Object []),而不是原本的 execute。

參考資料:
  1. http://developer.android.com/reference/android/os/AsyncTask.html
  2. http://blog.csdn.net/hitlion2008/article/details/7983449
  3. http://stackoverflow.com/questions/4068984/running-multiple-asynctasks-at-the-same-time-not-possible
  4. http://stackoverflow.com/questions/10480599/how-asynctask-works-in-android