編輯:關於Android編程
大家如果喜歡我的博客,請關注一下我的微博,請點擊這裡(http://weibo.com/kifile),謝謝
轉載請標明出處(http://blog.csdn.net/kifile),再次感謝
原文地址:http://developer.android.com/training/articles/memory.html
在接下來的一段時間裡,我會每天翻譯一部分關於性能提升的Android官方文檔給大家
下面是本次的正文:
################
隨機訪問存儲器(Ram) 不管在哪種軟件開發環境中都是一種極其寶貴的資源,而在移動開發平台下,極其有限的物理內存則更為寶貴。因此,雖然Android的Dalvik虛擬機會執行垃圾回收,但這不代表你可以對你應用的內存分配和釋放不聞不問。
為了使垃圾回收期能夠回收你應用中的內存,你需要避免內存洩露(通常是由於在全局變量持有某個對象引起的),以及在適當的時候釋放點引用對象(比如在生命周期中)。對於大多數應用而言,Dalvik虛擬機的垃圾回收器會幫你回收掉那些不再處於作用域中的對象的內存。
本文將介紹 Android 是如何管理內存進程以及內存分配,以及如何在開發過程中減少內存使用。如果對於 Java 的清理資源機制,你還希望了解的更多,那麼你可以去看看一些關於資源引用的書籍或者在線文檔。如果你正在尋找如何分析當前應用內存使用的資料,那麼你可以參考這篇文章(Investingating Your RAM Usage)。
Android 如何管理內存
Android 雖然沒有提供內存的交換空間,但是他使用了分頁和內存映射文件來管理內存。這代表任何你修改過的內存,不論是分配了一個新的對象,再或者是更改了內存映射夜的操作,都將在保留在內存,以至於不能被釋放。從你的應用中釋放這些內存唯一的方法就是將使用的對象釋放,使得垃圾回收機制能夠能夠回收他。唯一的例外是,對於那些沒有被更改的數據,例如代碼,當系統希望在別的地方使用他的時候,就被系統調用到哪裡。
公有內存
Android 為了在RAM中能夠存放盡量多的資源,因此他允許某些共有內存跨進程使用。他的原理如下:
1.每一個應用進程都是被一個叫做 Zygote 的進程負責出來的。Zygote 進程是在系統啟動的時候自動啟動的,並且內部加載了很多公用框架代碼以及資源(例如 Activity 主題等)。啟動一個新應用的時候,系統從 Zygote 進程中復制這些資源,然後在新進程中運行應用代碼。這就允許框架和資源中的大量內存資源被跨進程復用。
2.大多數靜態數據是通過內存映射放置到進程中。這不僅代表著同樣的數據能夠被跨進程分享,同樣代表著當需要的時候能夠隨時被調用。舉個例子,靜態數據包括:Dalvik 碼(使用預編譯的.odex來直接調用),應用資源(國通簡歷資源映射表來調用),以及一些默認的項目資源,例如在.so 文件中的本地代碼
3.在很多地方,Android 都會通過直接分配內存區域來跨進程分享同樣的動態 RAM。例如,窗口 Surface 使用公用內存在應用和屏幕排序,Cursor 緩存在 ContentProvider 和客戶端之間使用同樣的內存
由於公用內存的使用,我們需要關心你的應用需要使用多少內存。 如何正確分析應用內存使用請參看Investingating Your RAM Usage。
分配和釋放應用內存
以下是關於 Android 如何分配和釋放內存的部分:
1.每個進程的Dalvik 堆會被限制在一個虛擬內存范圍內。這代表著邏輯堆的大小可以隨著他的需要而增長(當然系統會限制每個應用的最大內存占用)
2.每個堆的邏輯大小和堆使用的物理內存並不是一樣。當檢查應用的堆的時候,Android 會計算一個叫做比例大小(PPS)的值,這會將與其他應用共享的髒數據和清潔數據都計算在內,你的PPS的總值將被系統認為是物理內存的值。更詳細的信息請查看Investingating Your RAM Usage。
3.Dalvik堆並不會壓縮堆的邏輯尺寸,這代表著Android並不會通過清理空間來減小堆得大小。Android只在堆沒有剩余空間的時候才對堆本身采取回收措施。但這並不代表被堆使用的物理內存可以得到釋放。在垃圾回收之後,Dalvik會掃描堆來找到不用的內存頁,並通過madvise將這些內存頁釋放到內核空間。因此大批量的分配或者釋放對象將會回收使用過的物理內存。盡管如此,從那些小的資源中回收內存空間效果並不是很好,因為存放這些小資源的分頁,很可能被其他對象所使用,導致不能釋放。
限制應用內存
Android為了保證自身的多任務環境,他為每一個應用設置了堆的硬件限制。這個限制取決於設備擁有多少RAM。如果你的應用已經達到了堆的上限,並且還希望分配更多的內存空間,那麼就會導致OOM。
在某種條件下,你或許希望知道在當前設備上系統最大允許的堆空間,打個比方說用來決定緩存的大小。那麼你可以通過查詢getMemoryClass()來獲取到這些系統數據,他會將你應用可用的內存作為一個int類型的值進行返回,這將會在下面被討論。
切換應用
當用戶在應用之間進行切換時,Android使用近期最少使用算法(LRU)將進程保存在一個前台應用組件列表中,而非存放在交換空間。比如說當用戶首次啟動一個應用的時候,該應用的進程就會被創建,但是當用戶離開這個應用的時候,應用卻沒有完全退出。系統將保存進程的緩存,這樣一來當用戶接下來返回到當前應用的時候,這個緩存就可以被盡可能快的調用,以提升進入程序的速度。
如果你的應用有一個緩存的進程,並且他保持了他所需要的內存,那麼即使在用戶沒有使用到他的時候,也會限制系統的整體性能。因此當系統內存資源不足的時候,他就可能會殺死那些最近沒有被使用到的進程。所以為了使自己進程能夠盡可能的保持,最好跟著下面的章節學習,將自己的資源進行釋放
如果希望了解更多關於進程在非前台環境下是如何被緩存,以及Android如何決定哪個進程被殺死的信息,那麼請參看進程與線程
好吧,終於要開始講解Activity的啟動流程了,Activity的啟動流程相對復雜一下,涉及到了Activity中的生命周期方法,涉及到了Android體系的CS模式,
近日,遇到一個Dialog半透明背景消失的問題,背景需求是自定義Dialog實現警告提示框:// 初始化警告彈出框 alertDialog = new EmpAlertV
原生應用不僅可以跳轉到RN頁面,也可以吧RN的組件放到原生應用中,作為原生應用的一部分。首先介紹如何把react native嵌入到android中,然後再介紹如何把RN
AIDL的理解:Service中的IBinder還記得我們在MyService中利用new IMyInterface.Stub()向上轉型成了IBinder然後在onBi