Android 手機記憶體不足問題

有好一陣子, 手機都在抱怨記憶體不足的問題.  我用的 Galaxy Note 有 1GB DDR 和 16 GB FLASH.  如果是 DDR 不足, 可以用手機助手…等軟體把不用的 task 清掉, 這個問題較小. 比較大的問題是 NAND 切給 data 的空間不足, 這個就不是外插一張 SD 卡的問題了.

關於 data 的空間不足, 主要原因是 android  會把內建的 NAND 分成幾個 partitionm 像是 boot, system, data,cache…. 等等, 當然也有分更細的. 像是 [1] 説到的 9~10 個 partition. 總之, 使用者可以自由使用來安裝 APK 的空間沒有想像中得大.  即使內建的 NAND 還有很大的空間, 但是它未必能給 APP 安裝使用. 我的手機就只有 2GB 可以放自己安裝的 APP. 所以不只是我, 別人也會遇到這個問題, 常見的建議如下:

1. 不要安裝太多 APP.

2. 把 APP 安裝到外部 SD 卡上.

3. 到設定程式管理員那裡把 cache 清一清.

4. 把 datamedia 底下的多媒體檔案清掉.

5. 把佔用資源很多的 APP 清掉, 例如 Platinum 雖然是好物, 但是它自己也很肥.

6. root 後把用不到的韓國 APP 殺掉! 例如 reader hub…等等.

7. root 後把 datadalvik-cache 清掉.

8. root 後把 dalvik-cache 搬到 SD 卡. [4-6]

9. root 後把 NAND 重新 partition

經過身體力行之後, 發現 7 是最有用的. 因為我雖然把不用的 APP 移除了, 但 Android 把它們的 Dalik 檔案 (一堆 .dex) 都保留了下來. 當我把整個資料夾 500 多個檔案清空, 然後重新開機, 雖然 Android 又針對還存在的 APP 優化了一次, 我確多了 100MB 以上的空間出來. 那些下載檔案放不下的問題就沒有再出現了.

方法 8 雖然比 7 更好, 不過反應速度不知道會不會變慢? 我的外接 SD 是 class 10, 理論上可以應付. 等到 7 撐不住了再來用 8.

至於方法 9, 這招我是不敢用.

[ref]

1.Android/partitions

2. 2013-07-17 [Android] App怎麼使用最Smart?關於App使用與系統效能調校的8個小撇步!

3. [Android] 何謂 dalvik cache?

4. Mounts2SD – Storage & Memory

5. Moving Dalvik Cache to SD Card.

6. 小V精簡dalvik-cache, 增加空間

 

Smart pointer 小註解

Smart pointer 是為了解決要了記憶體沒有還 – 導致 memory leak, 或是記憶體已經還了還在用 – 導致當機的問題. 直覺上, 還個記憶體好像並非難事, 何必大費周章呢? 主要是由函數返回指標時, 我們不能確定要在外面還還是裡面? 例如 [2] 所說的, 不是我 new 的, 需要我 delete 嗎?

DataGenerator DataGen;
int* A = DataGen.GetData();
delete A; // Should do this?

為了解決這個問題, 我們需要比較聰明的指標. 在 C++11 和 Android 裡面, smart pointer 的定義略有不同. 在 C++ 的話, 可以分為 3 種, 分別是: 前者的 unique ptr, shared ptr, waek ptr . 而 Android 裡面分為 strong pointer 和 weak pointer 兩種. 它們的定義分別如下 [1-2]. 如果是 MFC, QT… 的話, 都還有定義別種的 smart pointer [5-6], 基本上大同小異.

pointer 定義
unique_ptr 確保一份資源(被配置出來的記憶體空間)只會被一個 unique_ptr 物件管理的 smart pointer;當 unique_ptr 物件消失時,就會自動釋放資源。
shared_ptr 可以有多個 shared_ptr 共用一份資源的 smart pointer,內部會記錄這份資源被使用的次數(reference counter),只要還有 shared_ptr 物件的存在、資源就不會釋放;只有當所有使用這份資源的 shared_ptr 物件都消失的時候,資源才會被自動釋放。
weak_ptr 搭配 shared_ptr 使用的 smart pointer,和 shared_ptr 的不同點在於 weak_ptr 不會影響資源被使用的次數,也就是說的 weak_ptr 存在與否不代表資源會不會被釋放掉。
strong pointer 等同於 C++ 11 的 shared pointer
weak pointer 弱指針只能指一個 object, 所以沒有 counter. 它只是提供一個地址, 甚至還不能調用 object 的 member function 或是 variable.

強指針 (strong pointer = sp) 和一般的 shared_ptr 一樣, 透過 counter 來記錄有多少 “人" 引用這個 object?如果每個人都用完了, counter 歸零之後就可以被 free.  [1,4]  而弱指針 (weak pointer = wp) 並不理會還有沒有人用, 只要自己用完就可以 delete 了. 當然, 只有在同時也沒有強指針指到它才會被 delete. 參考 [5] 的例子.

ref1, ref2, ref5 都是強指針 sp, ref3 是弱指針 wp. ref4 是 promote 過後的弱指針. 弱指針也不永遠是扶不起的阿斗, 它可以用 promote function 升級為強指針  (寫到這邊, 電視上正在演 “見龍卸甲", 劉德華救阿斗耶…).

// 先定義 class, Android 用的是 frameworksbaseincludeutilsRefBase.h

namespace android {

class RefTest : public RefBase {
public:
    RefTest(int32_t id) : mID(id) {
        printf(“RefTest ctor: %dn", mID);
    }
    virtual ~RefTest() {
        printf(“RefTest dtor: %dn", mID);
    }
    int32_t id() const {
        return mID;
    }
private:
    int32_t mID;
};
// 測試 strong pointer 的函數

int strong_pointer() {

    sp<RefTest> ref1 = new RefTest(1);
    sp<RefTest> ref5;
    {
        sp<RefTest> ref2 = new RefTest(2);
        ref5 = ref2; // comment this out and check when the destructor of ref2 is called,
                          // ref5 又參考了 ref2
    }
    wp<RefTest> ref3 = ref1; // 弱指針也可以指向強指針, 但強指針不能指向弱指針.
    sp<RefTest> ref4 = ref3.promote(); // 弱指針可以 promote 為強指針
    if (ref4 == NULL) {
        printf(“RefTest object is destroyedn“); // 強指針和弱指針都沒有人用, 就可以回收了. 但還不會發生.
    } else {
        printf(“RefTest object %d is still aroundn", // 此時還有人用
            ref4->id());
    }
    ref4 = NULL; // ref4 清掉, ref3 是弱指針不用管, ref1 還在用
    ref1 = NULL; // comment this out to check to check change in prints
                         // ref1 也不用了.
    ref4 = ref3.promote(); // ref1 清掉, ref4 清掉, 所以 ref4 這次應該 NULL 了.
    if (ref4 == NULL) {
        printf(“RefTest object is destroyedn");
    } else {
        printf(“RefTest object %d is still aroundn",
            ref4->id()); // 清掉了
    }
    printf(“Before return n");
    return 0;
} 
強指標的觀念帶有 counter, 似乎已經相當完備; 為什麼有強指針以後, 還要有弱指針? 甚至要那麼麻煩地去升級弱指針呢? 其實弱指針並不像它的名字那樣一無事處, 它也具有立刻把記憶體立即釋放掉的優勢. 在 “IOS5 ARC 完全手冊" [9] 的文件裡面, 它把弱指針的用途做了說明.
這次的 reference 特別多, 因此本來想簡單寫完, 不料化簡為繁, 又化繁為簡, 前後竟然跨了四天.

[ref]

1. Android智能指针使用方法介绍

2. 避免 memory leak:C++11 Smart Pointer

3. What are strong pointers and weak pointers

4. android smart pointer – [1] 的原文

5. Smart Pointers to boost your code

6. dhav’s blog

7. QT smart point 智能指针

8. C++内存管理

9. ios 5 arc完全指南

Slice vs Tile in H.265

在 H.265 (HEVC) 的規格裡面多一個名詞 tile, 本來我們講 tile 都是說 memory 的排法不要照 scan line, 而是以 Macroblock 為單位, 以節省記憶體頻寬. 不過這個名詞在 H.265 已經有了正式的定義. 首先, 回顧一下 H.264 的名詞. 可以根據下圖來區別 Coded Video Sequence, AU 和 NAL [1].

接下來看一下比較舊的 slice 的定義.

Slice 的下一層是 slice segment. 由一個 independent slice segment 開始, 接著一串 dependent slice segment. 在同一個 AU (access unit, 正好就是解出一張) 裡面, 可以有多個 slice segment. 下圖的每一個框框是一個 coding tree unit (CTU) , CTU 可以再切割成 coding tree blocks [2, 4].

Tile 的分法永遠是矩形的. 看到灰色的 independent segment就是一個 slice 的開頭, 後面白色的部分就是 depedent segments. 一個tile 可以包含多個 slice, 一個slice 也可以跨多個 tile. 不過還是要有一些規則.

首先記住 CTU 會組成 coding tree, 接著至少要滿足下面兩個條件之一:

1. 所有的 slice 的 CTU 都完整地在一個tile 內.

2. 所有的 tile 的 CTU 都完整地在一個 slice 內.

其中, 1 的條件也可以延伸為 “所有的 slice segment的 CTU 都完整地在一個tile 內. 比 2 的條件再更嚴格一點的話, 就是所有的 tile 的 CTU 都完整地在一個 slice segment內. 規格書說, 上述兩個條件也要至少滿足其中之一.

此外, 我們有 Y/U/V 三個平面 (plane), 如果 separate_colour_plane_flag = 0, 那麼表示大家的slice 都長一樣. 若是這個值等於 1, 表示三個平面可以有自己的 slice. 此時, 三個平面的資料在同一個 AU裡面可以交錯 (interleave). 但是同一個 plane id 裡面的 coded slice segment NAL unit 只能依照 tile order 遞增.

那 tile 有什麼用呢?它是可以平行處理的單位. 也就是說, decoder 可以同時對多個 tile 進行解碼. 以前我們要解完一個 slice, 才能再解下一個 slice, 否則也不知道下一個 slice 的 header 在哪裡?現在我們只要知道有幾個 tile, 就可以從 tile 的頭開始解碼. Tile 不像 slice 有 header, 所以不會又多一層 overhead.

那麼, 我們怎麼找到 tile 的開頭呢?從 bit stream 裡面可以找到這一段定義.

首先就看有沒有 enable tile (tiles_enabled_flag = 1), 有的話再看是不是均勻的大小 (uniform_spaciing_flag). 如果 tile 並不一樣大, 就分別讀出每一個 tile 的寬高. 雖然 bit stream 沒有直接講出寬高, 只要在畫面上下砍 column_width_minus1 刀, 橫切 row_height_minus1 刀就可以得到這些格子了.

在 [ref 3] 裡面, 有人提到 tile 可以做 ROI (region of interest, 不是 return on investment). 先畫一個 tile 放重點, 給比較高的 bit rate; 其他的小 tile 就給比較低的 bit rate. 由於 H.265 裡面拔掉了 H.264 的 FMO (flexible MB order),  所以光靠 slice 就不方便做這種匡出一塊矩形效果. 另外, 這邊有人吐槽 FMO 本來就是做 error concealment 用的, 不是 ROI 用的.

[REF]

1. H.264先進視訊編解碼標準

2. H.265 Spec.

3. I am littile confused about the tiles in HEVC. Can’t we achieve same parallelism using only slices?

4. HEVC – What are CTU, CU, CTB, CB, PB, and TB?

[速覽]

CB vs sub-block

CU = YUV 的 CB + syntax element

CTB (8×8~64×64) vs MB (16×16)

CTU = YUV  的 CTB + syntax element

UML 類別圖符號

最近又看到一堆 UML 的類別圖, 特別整理了一個符號速查表.
 
 inheritance  B A 繼承 B
 realization AB A 實現 B
 association              B A 關聯 B
 單向 association  B A 關聯 B 
 dependency B A 依賴 B
 註解 A B A 註解 B
 aggregation  B A 彙總 B
 composition  B A 組合 B
 relationship A <<key word>> B access, bind,derive…etc.

[REF]

1. UML類別圖

 

阿里雲小檔案

阿里雲 (Aliyun) 顧名思義是阿里巴巴的產品, 也是該公司的名稱. 藉著阿里巴巴集團下的淘寶, 支付寶, …等子公司的互相支援下, 阿里雲竟然也在競爭激烈的 OS 市場佔了一席之地.

既然叫做 “雲", 強調的就是雲端技術, 我們可以把阿里雲這家公司想要賣的東西先交代清楚, 然後再來看它會做些什麼?而他的客戶又要做什麼?

對阿里巴巴來說, 他們和其他的雲端公司一樣想要賣網路伺服器, 希望大家把東西存在他們基於飛天開放平台 (Apasara) 的 server 上. 除了硬體也要有軟體, 所以飛天開放平台上也提供: 計算, 存儲, 和資料庫的服務. 就好比 Google 有 gmail, Google doc, Google maps…一樣.

至於大家共通的雲 OS, 則是架在 Linux, Webkit/HTML5/Java Script, OpenGL 和 SQLite 上. 阿里雲號稱他們是基於 Linux, 但 Google 說他們是抄 Android 的 [3], 證據是阿里雲用了 Android 的 run-time lib, framework, 和 tools [4], 也可以跑山寨版的 Google App. 雖然 Google 有反分裂法 (AFA – anti fragmented Agreement), 嚴禁 Android 的客戶自己搞一套服務, 但是阿里雲不但有樣學樣, 竟然還定義了新的指令集! 

根據 [5] 的說法, 我做了個表, 大家變可以知道他們大致上的差異. 據說安兔兔也不能分辨 Android 和 Aliyun. [5] 這篇也講了阿里雲開發的秘辛, 有興趣的人可以參考.

Android 阿里雲
boot loader boot.img 同左
kernel Linux 同左
ROM 目錄結構 app/bin/framework/lib 同左
核心進程 system/bin 同左
 library (.so) system/lib 同左
Framework system/framework 同左
上層 app, launcher system/app 同左
app 副檔名 apk lar
apk 解開之後 class.dex class.lex
虛擬機 (VM) Dalvik 自製 VM

倒底阿里雲好不好用呢?[2] 這篇講得比較詳細, 一共列出 16 點. 其中最大的特色就是阿里雲綁架了桌面, 也限制了阿里雲以外的應用. 如果是阿里雲 market 裡的軟體, 就可以自動備份到雲端. 但是不支援 Google market , 第三方的 app 和 widget 也不提供雲端備份的服務. 基本上就是與 Android 分裂, 另外搞了一個生態圈.

 [ref]

1. 百度百科 – 阿里雲

2. 说说阿里云OS操作系统到底是什么货色

3.  Google 阻止宏碁與阿里雲合作的真實原因

4.  Google+ 文章

5. 纯技术分析阿里云OS和Android之间的关系