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

 

阿里雲小檔案

阿里雲 (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之间的关系

Miracast in Android 小整理

大家都知道 Android 4.2 版支持了以前叫做 WIFI Display 的 Miracast. 看了同事轉寄的網路文章 [1], 才知道 Android 連架構都配合 Miracast 做了修改.

首先考量的是, 使用者需要把手機上的畫面輸出到電視上分享給大家, 卻不能讓大家都看見他/她怎麼在鍵盤上按密碼. 所以 surfaceflinger 就不能把虛擬鍵盤或是密碼框的這一層投射出去. 換言之, 把整個 display planes  (什麼 V1, V2, OSD1, OSD2, SUB1, SUB2) 都 mix 後才輸出的那張圖, 反而不是可以公開的.

因此, surfaceflinger 裡面就多了個 display device 的抽象層.

DISPLAY_PRIMARY:  Android 手機的螢幕

DISPLAY_RXTERNAL: HDMI 設備, 如 TV

DISPLAY_VIRTUAL: WIFI Display, 即 Miracast.

1357478805_4074

對於 virtual 的裝置, Android 並不準備它的 frame buffer.從下面這段 code 中可以看出, 每一個 Display Device 在產生的時候, 都會參考 state.isVirtualDisplay 是否為真? 進而決定 hw 這個 class 的內容. Miracast 顯然就和 HDMI, 和 local 螢幕不同類. 可見得在 HDMI 以 MHL (Mobile High-Definition Link) 接電視的情況下是允許看到輸入密碼視窗的, 但 Miracast 以 WIFI 無線時不可以顯示.

1357478788_3356

其中 static_cast< sp<ISurfaceTexture>> 表示指定型別為 sp<ISurfaceTexture>, 也就是 ISurfaceTexture 的 smart pointer. Smart pointer 也是個 pointer, 它有助於在不同的地方 create 和 destroy, 因此可以靈活地運用並減少記憶體丟失 (或曰"洩漏").它的原文是:

Smart pointers ensure we properly destroy an object even if its creation and destruction are widely separated. They make functions simpler and safer by ensuring that no matter how many different exit paths exist, local objects are always cleaned up correctly. They help enforce that exactly one object owns another object at any given time, preventing both leaks and double-frees.[2]

最後 Android 做 composer 的時候, 會對每一種顯示設備 (共 mDisplays.size 種) 檢查是否 dirty (需要更新)? 並且用 hw->canDraw() 判斷能不能畫? 如果不能畫, 連 dirty 也不畫.在 2011 年的時候, 就有人抱怨過 hw->flip 為什麼在 hw->canDraw() 的前面執行 [3]? 導致 Android suspend 的時候都還在 flip. 看來 Android 是從善如流, 改為優先判斷 canDraw() 了.

1357478824_6904

[REF]

1.Android Wi-Fi Display 介紹

2.Smart Pointer Guidelines

3.Android的Suspend​

Android APP 對 memory 的要求

剛剛在 Android 4.2 CDD (Compatibility Definition Document) 裡面看到 Android 對 APP 指定了可以給予多少 memory 的參考數字.

不過該表格使用的單位很不直覺, 它定義了 small, normal, large, xlarge 四種螢幕尺寸; 又定義了 ldpi, mdpi, tvdpi, hdpi, xhdpi, xxhdpi 等六種解析度 (DPI = dot per inch).

雖然我們可以顧名思義地推測, xlarge 就是 extra large. hdpi 就是 high DPI 等等. 還是做一張沒有特殊名詞, 直接看數字的表格來參考比較方便.

Screen Size Screen Density (DPI) Application Memory (MB)
426×320/480×320/640×480 120~160 16
213~240 32
320 64
960×720 160 32
213~240 64
320 128

據說真正的視網膜解析度是 477 DPI, 而 iphone 4 超越的視網膜 326 DPI 是指直線的方向而已.

總而言之, 在 Android APP 的世界裡, 還沒有 1080P, 4K2K, 或是超越視網膜這回事. 不然每個 APP 應該可以要個 256 MB 也不為過. 那 PM 就不用再想 "cost down 到一顆 256 MB DRR 有沒有可能?" 這種事了.

不過 Android 的確定義了兩種螢幕類型 (screen types). 一種是固定螢幕解析度 (Fixed-Pixel Device), 例如手機和平版. 所有的視訊都要縮放到它預設的解析度. 另一種類型 (Variable-Pixel Device) 是沒有螢幕, 或是有視訊輸出接口的. 對於後者, Android 就有 HD video 的觀念. 而且它很固執地規定只能有 720P 和 1080P 兩種解析度, 不准支援其它的輸出解析度.

Variable-pixel device implementations MUST support one or both of 1280×720, or 1920×1080 (that is, 720p or 1080p).

Android 的人對 GPU 的說法

由於很多人都認為 Android 3.0 以前, Android 只用軟體畫圖, 所以 Android  的人跑出來澄清. 雖然這篇文章已經有點久了, 正好可以呼應我上一篇的貼文. 有興趣的人可以去看原版 Dianne Hackborn 的 Google+, . 我在這邊只摘要幾個重點.

1. Android 從 1.0 版就使用硬體加速視窗的的疊加 (all window compositing to the display has been done with hardware), 當然有的時候會用軟體. 下圖共包含四層視窗 (windows): Wall Paper, Launcher, Menu, Status Bar. 如果使用者操作 menu, 只有 menu 會用軟體重畫. 而疊加 (overlay) 的部分和整張畫面滑動的效果則是用硬體做.

2. Android 3.0 開始全部由硬體加速, 4.0 也是一樣. 只不過 Android 3.0 會檢查 App 在 manifest 裡面的 “android:handwareAccelerated="true" 這行 , 以決定是否用硬體加速. 而 Android 4.0 預設就是全部用硬體加速. 這麼一來, 原本只需要局部 UI 更新的狀況也不再交給比較有效率的軟體來執行了; 如此一來導致了一些副作用.  

3. 其他用硬體加速的缺點包括浪費記憶體, Imagination Tech 的繪圖驅動程式基本上要吃掉 8MB RAM. 剩餘的 RAM 變少了, 其它的背景程式就會變慢. 因此, status bar 其實不需要用 OpenGL (GPU) 來畫. Android 4.0 就把這部分單獨用軟體處理.

4. 蘋果的 IOS 怎麼做呢? 以瀏覽器為例, IOS 把網頁的畫面以 display list 的方式來畫, 因此沒有什麼更新區域的概念, 整個頁面都要重畫. 這麼做的優點是捲動或試放大縮小的時候不會看見破圖 (artifact) – 假如畫面是分成幾個區塊 (title) 來分別渲染的話, 就可以會有 artifact. 後者恰好就是 Android 的做法, 它比較能夠對抗複雜的頁面而不致於變慢, 因此光是用軟體就可以在 Nexus S2 畫出每秒 60 楨 (60 fps). 作者說他相信 IOS 也是用軟體畫的.

5. 為了解決 GPU 不夠力的問題, Android 還是有用 HW overlay, 而且把底圖 (backgound) 放的比螢幕還大. 這樣一來, 使用者捲動畫面的時候, 底圖就不需要重畫, 只是改個座標 (offset) 而已.

6. 當我們用 CPU 畫 UI 的時候, 多核心並沒有幫助. 因為幫一個 app 繪製 UI 的時候, 沒辦法做平行處理. 這就是為什麼 Android 要用 GPU 加速. 在去年年底 Galaxy S2 出來的時候, ARM 的 CPU (大約是 CA9 1GHz) 還不能畫到 720×1280 的 UI (60 fps), 因此更細緻的解析度都必須仰賴 GPU 來畫.

以下再補充更多的觀點:

7.  Android 官網的說法: GPU 擅長放大縮小, 旋轉,  平移, 但是不擅長畫直線和曲線. 所以要多用其長, 少用其短.

8. Qualcomm 說 Android 在他們的 Snapdragon 可以用 GPU 做 composition (也就是不用 HW overlay):

如果 graphic UI (user interface) 和 video 沒有同步, 那麼一般人腦海中的狀況是這樣:

 Qualcomm 說: video 可以當作圖形處理中的紋理 (texture), 所以簡單多了.