記憶體優化技巧

若蘭__明月發表於2018-01-03
  • 1、使用Service的風險

    • 如果應用程式當中需要使用Service來執行後臺的任務的時候,請一定要注意只有當任務正在執行的時候才應該讓 Service執行起來,另外,當任務執行完之後去停止Service的時候,要小心Service停止失敗導致記憶體洩露的問題 當我們啟動一個Service的時候,系統會傾向於將這個Service所依賴的程式進行保留,這樣就會導致這個程式變得 非常消耗記憶體,並且,系統可以在Lru Cache當中快取的程式數量也會減少,導致切換應用程式的時候消耗更多的效能 嚴重的話,甚至有可能會導致崩潰,因為系統在記憶體非常吃緊的時候可能已無法維護所有正在執行的Service所依賴的程式了 為了能夠控制Service的生命週期,Android官方推薦的最佳解決方案就是使用IntentService,這種Service的最大的特點就是 當後臺任務執行結束會自動停止,從而極大程度上避免了Service記憶體洩露的可能性
  • 注意: 讓一個Service在後臺一直保持執行,及時它並不執行任何工作,這是編寫Android程式時候最糟糕的做法之一

  • 2、當介面不可見時釋放記憶體

  • 當使用者開啟另一個應用程式的時候,我們的程式介面已經不再可見的時候,我們應當將所有和介面相關的資源進行釋放 只需要在Activity中重寫onTirmMemory()方法,然後在這個方法中監聽TRIM_MEMORY_UI_HIDDEN這個級別,一旦觸發了之後就 說明使用者已經離開了我們的額程式,那麼此時就可以進行資源釋放操作了:

 @Override
				public void onTrimMemory(int level) {
					super.onTrimMemory(level);
					switch (level){
						case TRIM_MEMORY_UI_HIDDEN:
							//進行資源釋放操作
							
							break;
					}
				}
複製程式碼
  • 3、當記憶體緊張時候釋放記憶體

    • 1)onTrimMemory()方法還有很多其他型別的回撥,可以在手機記憶體降低的時候及時通知我們,我們應該根據回撥中傳入的 級別來決定如何釋放應用程式的資源
    • 2)TRIM_MEMORY_RUNNING_MODERATE 表示程式執行正常,不會被殺掉,但是記憶體已經有點低了,系統可能會開始根據LRU 快取規則 去殺死程式了
    • 3)TRIM_MEMORY_RUNNING_LOW 表示程式正常執行,不會被殺掉,但是記憶體已經非常低了,我們應該去釋放掉一些不必要的資源以提升系統的效能,同時這也會直接影響到我們應用程式的效能
    • 4)TRIM_MEMORY_RUNNING_CRITICAL 表示程式正常執行,但是系統已經根據LRU快取規則殺掉了大部分快取的程式,我們應當儘可能 的去釋放任何不必要的資源,否則系統可能會殺死所有快取中的程式,並且開始殺掉一些本來應當保持執行的程式,比如說後臺的服務
    • 5)如果我們的程式目前是被快取的則會收到一下幾種型別的回撥
      • 1>TRIM_MEMORY_BACKGROUMD 記憶體已經很低了,系統準備開根據LRU快取來清理程式,這個時候我們的程式在LRU快取列表的最近的位置,是不太可能被清理掉的,但這個時候釋放掉一些比較容易恢復的資源能夠讓手機的記憶體變得比較充足,從而我們的程式更長時間的保留到快取中,這樣當用於返回我們的程式的時候會感覺非常流暢,而不是經歷了一次重新啟動
      • 2>TRIM_MEMORY_MODERATE 記憶體已經很低了,並且我們的程式處於LRU快取列表的中間位置,如果手機記憶體還得不到進一步的釋放的話,那麼 我們的程式就有可能被系統殺死的風險了
      • 3>TRIM_MEMORY_COMPLEIE 記憶體已經很低了,並且我們的程式處於LRU快取列表的最邊緣位置,系統會最優先考慮啥我我們的應用程式,在這個時候應當 竟可能的把一切可以釋放的東西進行釋放
  • 4、避免Bitmap上浪費記憶體

  • 5、使用優化過的資料集合 比如SparseArray(核心是折半查詢函式) SparseBooleanArray 以及LongSparseArray

  • 6、瞭解記憶體的開支情況

    • (1)使用列舉通常會比使用靜態常量要消耗兩倍以上的記憶體,
    • (2)任何一個Java類,包括內部類,匿名類,都要佔用大概500位元組的記憶體空間
    • (3)任何一個類的例項要消耗12-16位元組的記憶體開支,因此頻繁的建立例項也是會在一定程度上影響記憶體的
    • (4)在使用HashMap得時候,即使你設定了一個基本資料型別的鍵,但是也會按照物件的大小來分配記憶體,大概是32位元組,而不是4位元組,因此最好的辦法是使用優化過的資料集合
  • 7、反抽象程式設計理念 在面象物件的世界裡,使用抽象程式設計是一種被崇尚的程式設計習慣,使用抽象程式設計在程式碼的維護和可擴充套件性方面都會提高很多,但是在Android上使用抽象會帶來額外的記憶體開支,因為抽象的程式設計方法需要編寫額外的程式碼,雖然這些程式碼根本執行不到,但是確也對映到記憶體當中,不僅佔用了更多的記憶體,在執行效率方面也會有所降低

  • 8、避免使用依賴注入框架 這些框架為了要搜尋程式碼中的註解,通常需要經歷較長的初始化過程,並且還可鞥將一些你用不到的物件也一併載入記憶體當中,並且用不到的物件會一直佔用記憶體,可能要過很久之後才能得到釋放

  • 9、使用ProGuard混淆程式碼 ProGuard通常大家認為是一個混淆程式碼的工具,但是除了混淆之外,它還具有壓縮和優化程式碼的功能,ProGuard會對我們的程式碼進行檢索刪除一些無用的程式碼,並且會對類、欄位、方法進行重新命名,重新命名之後的類、欄位、方法都會比原來的簡短很多。釋放好多記憶體

  • 10、使用多個程式 想要實現多程式的功能也是非常簡單的,只需要在manifest檔案的應用程式元件中宣告一個android:progress屬性就可以了比如說我們希望播放音樂的Service可以執行在一個單獨的程式當中

<service anroid:name=".PlayBackService"
							android:progress=":backgroud"/>
複製程式碼

相關文章