Android最佳化-與Java有關-記憶體

來源:互聯網
上載者:User

標籤:

 


記憶體最佳化

  Android系統對每個軟體所能使用的RAM空間進行了限制(如:Nexus one 對每個軟體的記憶體限制是24M),同時Java語言本身比較消耗記憶體,dalvik虛擬機器也要佔用一定的記憶體空間,所以合理使用記憶體,彰顯出一個程式員的素質和技能。

  1) 瞭解JIT

  即時編譯(Just-in-time Compilation,JIT),又稱動態轉譯(Dynamic Translation),是一種通過在運行時將位元組碼翻譯為機器碼,從而改善位元組碼編譯語言效能的技術。即時編譯前期的兩個運行時理論是位元組碼編譯和動態編譯。Android原來Dalvik虛擬機器是作為一種解譯器實現,新版(Android2.2+)將換成JIT編譯器實現。效能測試顯示,在多項測試中新版本比舊版本提升了大約6倍。

 

 

避免建立不必要的對象

  就像世界上沒有免費的午餐,世界上也沒有免費的對象。雖然gc為每個線程都建立了臨時對象池,可以使建立對象的代價變得小一些,但是分配記憶體永遠都比不分配記憶體的代價大。如果你在使用者介面迴圈中指派至記憶體,就會引發周期性的記憶體回收,使用者就會覺得介面像打嗝一樣一頓一頓的。所以,除非必要,應盡量避免儘力對象的執行個體。下面的例子將協助你理解這條原則:當你從使用者輸入的資料中截取一段字串時,盡量使用substring函數取得未經處理資料的一個子串,而不是為子串另外建立一份拷貝。這樣你就有一 個新的String對象,它與未經處理資料共用一個char數組。 如果你有一個函數返回一個String對象,而你確切的知道這個字串會被附加到一個StringBuffer,那麼,請改變這個函數的參數和實現方式, 直接把結果附加到StringBuffer中,而不要再建立一個短命的臨時對象

  一個更極端的例子是,把多維陣列分成多個一維數組:

  int數組比Integer數組好,這也概括了一個基本事實,兩個平行的int數組比 (int,int)對象數組效能要好很多同理,這試用於所有基本類型的組合。如果你想用一種容器儲存(Foo,Bar)元組,嘗試使用兩個單獨的 Foo[]數組和Bar[]數組,一定比(Foo,Bar)數組效率更高。(也有例外的情況,就是當你建立一個API,讓別人調用它的時候。這時候你要注重對API介面的設計而犧牲一點兒速度。當然在API的內部,你仍要儘可能的提高代碼的效率

  總體來說,就是避免建立短命的臨時對象。減少對象的建立就能減少垃圾收集,進而減少對使用者體驗的影響。

盡量避免在經常調用的方法,迴圈中new對象,由於系統不僅要花費時間來建立對象,而且還要花時間對這些對象進行記憶體回收和處理,在我們可以控制的範圍內,最大限度的重用對象,最好能用基本的資料類型或數組來替代對象

總體來說,就是避免建立短命的臨時對象。減少對象的建立就能減少垃圾收集,進而減少對使用者體驗的影響。

 

 

減少不必要的全域變數

  盡量避免static成員變數引用資源耗費過多的執行個體,比如Context。Android提供了很健全的訊息傳遞機制(Intent)和任務模型(Handler),可以通過傳遞或事件的方式,防止一些不必要的全域變數。

 

不要過多指望gc

  Java的gc使用的是一個有向圖,判斷一個對象是否有效看的是其他的對象能到達這個對象的頂點,有向圖的相對於鏈表、二叉樹來說開銷是可想而知。所以不要過多指望gc。將不用的對象可以把它指向NULL,並注意代碼品質。同時,顯示讓系統gc回收,例片處理時,

if(bitmap.isRecycled()==false) { //如果沒有回收     bitmap.recycle();}

 

 

 

盡量避免隨意使用靜態變數

要知道,當某個對象被定義為stataic變數所引用,那麼gc通常是不會回收這個對象所佔有的記憶體,如

public class A{    static B b = new B();}

 

 

將成員緩衝到本地

訪問成員變數比訪問本地變數慢得多,下面一段代碼:

for(int i =0; i <this.mCount; i++)  {dumpItem(this.mItems);}

 最好改成這樣:

int count = this.mCount;Item[] items = this.mItems;for(int i =0; i < count; i++)  {       dumpItems(items);}

 

另一個相似的原則是:永遠不要在for的第二個條件中調用任何方法。如下面方法所示,在每次迴圈的時候都會調用getCount()方法,這樣做比你在一個int先把結果儲存起來開銷大很多。

for(int i =0; i < this.getCount(); i++) {dumpItems(this.getItem(i));}

 

 同樣如果你要多次訪問一個變數,也最好先為它建立一個本地變數,例如:

protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) {    if(isHorizontalScrollBarEnabled()) {        intsize = mScrollBar.getSize(false);        if(size <=0) {               size = mScrollBarSize;        }        mScrollBar.setBounds(0, height - size, width, height);        mScrollBar.setParams(computeHorizontalScrollRange(), computeHorizontalScrollOffset(), computeHorizontalScrollExtent(),false);        mScrollBar.draw(canvas);    }}

這裡有4次訪問成員變數mScrollBar,如果將它緩衝到本地,4次成員變數訪問就會變成4次效率更高的棧變數訪問

 

如果mScrollBar 只是 一個 基礎資料型別 (Elementary Data Type),直接存取是可以接受的; 但如果mScrollBar 是一個 複雜的對象,需要 複製過來比較好, 因為如果訪問的話,

 

另外就是方法的參數與本地變數的效率相同。

 

 

盡量早釋放無用對象的引用

大部分時,方法局部引用變數所引用的對象 會隨著方法結束而變成垃圾,因此,大部分時候程式無需將局部,引用變數顯式設為null。

Public void test(){    Object obj = new Object();    ……    Obj=null;}

 

上面這個就沒必要了,隨著方法test()的執行完成,程式中obj引用變數的範圍就結束了。但是如果是改成下面:

Public void test(){    Object obj = new Object();    ……    Obj=null;    //執行耗時,耗記憶體操作;或調用耗時,耗記憶體的方法    ……}

這時候就有必要將obj賦值為null,可以儘早的釋放對Object對象的引用。

 

 

 

盡量緩衝經常使用的對象

儘可能將經常使用的對象進行緩衝,可以使用數組,或HashMap的容器來進行緩衝,但這種方式可能導致系統佔用過多的緩衝,效能下降,推薦可以使用一些第三方的開源工具,如EhCache,Oscache進行緩衝,他們基本都實現了FIFO/FLU等緩衝演算法。

 

 

盡量避免非常大的記憶體配置

有時候問題不是由當時的堆狀態造成的,而是因為分配失敗造成的。分配的記憶體塊都必須是連續的,而隨著堆越來越滿,找到較大的連續塊越來越困難。

 

 

緩衝

適量使用緩衝,不要過量使用,因為記憶體有限,能儲存路徑地址的就不要存放圖片資料,不經常使用的盡量不要緩衝,不用時就清空。

 

 

Android最佳化-與Java有關-記憶體

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.