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, 增加空間

 

我讀 «地獄»

丹布朗又出新書了! 昨天到貨的 <Inferno> 終於讀完.

延續過去一貫的風格, 這本書依然環繞著歷史、密碼、符號, 以及人類的生存危機 – 生理上或是心理上的. 至於這次的危機是什麼? 我就不爆料了. 反正全書開始不久就有暗示, 最後峰迴路轉, 不是大家想的那一個的 “那個", 一樣有暗示啦, 讀到最後幾章就能猜得到.

另外, 丹布朗慣用的手法還是好人變壞人, 壞人變好人, 然後又變回來一次的那招. 不過這次的女主角是智商 208 的金髮美女醫師, 我們當然不想她死得太快或是變成壞人囉. 只是作者變變變的梗用太多, 害我連主角的名字都不能寫, 不然立刻就破梗了~~~ 幸好主角還是哈佛大學的教授蘭登, 這個始終一以貫之.

什麼都不能講要講什麼呢? 我想講歷史和地理. 這次的書名叫做地獄, 其實是引用自但丁的神曲, 整個事件都和但丁有關. 話說但丁的神曲描述了地獄、煉獄、和天堂. 但重點大概是在地獄. 地獄共有九層, 像是個漏斗. 撒旦就在最下面. 第一層是給不認識基督的異教徒用的. 不知者也是有罪, 尼安德塔人得在此聽候上帝的審畔. 異端者會受到火刑, 貪食者吃屎等等.

爬過撒旦的尾巴就來到煉獄. 煉獄是分為七層的高山, 靈魂在這邊領到集點卡之後, 每爬上一重山, 就可以消除一種最孽. 犯了七宗罪的人洗去他的罪, 就可以在山頂進入天堂. 而天堂也有九層, 到了最高層的天堂才能見到三位一體的神. 除罪這個動作就是本書解密的梗之一.

另外地獄八層的罪狀和七宗罪非常接近, 就是 貪食色慾貪婪悲嘆暴怒懶惰自負傲慢. 也就是說自負的人在地獄是有罪的, 但是在煉獄就還 OK, 不列入考核.

七宗罪各自都有一些懲罰的方式, 這也是解謎的梗. 罰錯了方式可不行.

拉丁文 中文
superbia 驕傲
invidia 妒忌
ira 暴怒
accidia 懶惰
avaritia 貪婪
gula 貪食
luxuria 色慾

話說神曲和我們在廟裡看到的 “善書" – 像是天堂遊記、地獄遊記有什麼不同呢? 主要就是文學性. 神曲雖是通俗文學, 但是每三行連韻. WIKI 說: “全詩為三部《地獄篇》《煉獄篇》《天堂篇》,每部33首,最前面增加一首序詩,一共100首。詩句是三行一段,連鎖押韻,各首長短大致相等,每部也基本相等。(地獄4720行;煉獄4755行;天堂4758行),每部都以「群星」(stelle = 英文 star)一詞結束。"  以 star 結束也是一個梗.

除了但丁的神曲, 書中還有許多歷史地理, 特別是與神話相關的歷史. 例如聖露西亞 – 盲人骨頭. 我隨著主角的行程用 Google Map 網游, 也就順便導覽了這些地方. 聖母百花大教堂是綠的、粉紅的、白色的…呃…不看圖還真難明白. 用 GooleMap 大概就能知道作者在講什麼.

佛羅倫斯的聖喬凡尼洗禮堂距離大教堂有多遠? 天堂之門長什麼樣子?

主角在威尼斯大運河西方起點時, 看到的小聖梅西歐教堂有所謂拜占庭的圓頂、古希臘的石柱和山形牆…看圖吧!

有圖之後讀書就更有趣了. 可惜 Google Map 竟然用著用著就在威尼斯當了. 我只好升級成新版的 Google Map. 但用起來一時不習慣. 放 “菊色小人" 在地圖上的介面改了,  幾個地方也就沒有查下去. 看來以後有時間再來網遊伊斯坦堡的蘇非亞大教堂和蓄水池吧!

其實本書還有一個 APP: Dan Brown Inferno", 掃瞄本書的封面就有機會得到簽名書. 不過中文版的封面它好像不認得呢? 我只好放棄了! 其實我倒是希望有實境導覽的 APP, 這樣就可以更有親臨現場的感受. 畢竟 Google 也不容易查到所有建築物的內部裝潢, 那部份都只能靠想像彌補. 但有了這麼好的 APP 或是電子書, 應該會影響電影的版權收入吧! 哈!

耗時六小時的讀書和兩小時的網誌就先告一段落了. 這次義大利犀牛的第四戰輸得更少了, 還打到延長賽. 不過還是四連敗被清盤, 和我預期地差不多. 因為不忍心看轉播, 就專心看書. 希望明年中華職棒還是至少有四隊, 其他不強求.

[ref]

1. 但丁 <<神曲>>

2. WIKI: 神曲

3. 七宗罪

4. 解碼丹布朗

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類別圖