Android內存優化指南:從數據結構到5R法則的全面策略

目錄

一、APP 內存限制

二、內存的三大問題

2.1、內存抖動(Memory Churn)

2.1.1 頻繁創建短生命周期對象

2.1.2 系統API或第三方庫的不合理使用

2.1.3 Handler使用不當

2.2、內存泄漏(Memory Leak)

2.2.1 靜態變量持有Activity或Context引用

2.2.2 未取消的回調或監聽器

2.2.3 非靜態內部類持有外部類引用

2.2.4 Timer或Handler未正確取消

2.2.5 Bitmap未及時回收

2.2.6 資源文件未關閉

2.2.7 WebView

2.3、內存溢出(OutOfMemoryError)

2.3.1 為對象分配內存時達到進程的內存上限

2.3.2 沒有足夠大小的連續地址空間

2.3.3 創建線程失敗

2.3.4 內存泄漏積累

2.3.5 集合類對象未及時清理

三、內存問題解決方案

3.1 選擇合適的數據結構

3.2 避免使用枚舉

3.3 謹慎使用多進程

3.4 謹慎使用 Large Head

3.5 使用NDK

四、 圖片優化

4.1 如何對圖片進行緩存?

4.2 計算圖片占用內存的大小

4.3 如何計算圖片占用內存的大小?

4.4 圖片內存體積優化總結

五、內存優化5R法則

相關推薦


一、APP 內存限制

        Android 給每個 App 分配一個 VM ,讓App運行在 dalvik 上,這樣即使 App 崩潰也不會影響到系統。系統給 VM 分配了一定的內存大小,App 可以申請使用的內存大小不能超過此硬性邏輯限制,就算物理內存富余,如果應用超出 VM 最大內存,就會出現內存溢出 crash。

        由程序控制操作的內存空間在  heap 上,分 java heapsizenative heapsize

        Java申請的內存在 vm heap 上,所以如果 java 申請的內存大小超過 VM 的邏輯內存限制,就會出現內存溢出的異常。(如:-Xmx4096)

        native 層內存申請不受其限制,native 層受 native process 對內存大小的限制。

        Android 虛擬機申請內存最大內存是有限制的,不同設備申請的最大內存是不一樣的。

二、內存的三大問題

        1、內存抖動:內存波動圖形呈 鋸齒張、GC導致卡頓。

        2、內存泄漏:在當前應用周期內不再使用的對象被GC Roots引用,導致不能回收,使實際可使用內存變小。

        3、內存溢出:即OOM,OOM時會導致程序異常。Android設備出廠以后,虛擬機對單個應用的最大內存分配就確定下來了,超出這個值就會OOM。

2.1、內存抖動(Memory Churn)

        內存抖動是指內存頻繁分配和回收,導致內存曲線呈鋸齒狀波動,可能導致應用頁面卡頓或響應緩慢常見的內存抖動場景及解決方案:

2.1.1 頻繁創建短生命周期對象

        在循環或頻繁調用的方法中創建大量短生命周期的對象,如字符串拼接、對象頻繁創建等。

        在自定義控件的onMeasureonLayoutonDraw等方法中創建對象,由于這些方法會頻繁調用,導致對象頻繁創建和回收。

解決方案

  • 避免在循環或頻繁調用的方法中創建對象。
  • 使用StringBuilder等高效字符串拼接方式替代加號拼接。
  • 在自定義控件的繪制方法中,盡量復用對象,避免頻繁創建。
  • 對于需要頻繁創建和銷毀的對象,可以考慮使用對象池來復用對象。對象池能夠減少對象的創建和銷毀次數,從而降低內存抖動的發生概率。

2.1.2 系統API或第三方庫的不合理使用

        調用系統API或第三方庫時,沒有合理使用其提供的對象復用機制,導致大量對象被創建。

解決方案

  • 深入了解系統API和第三方庫的工作原理,合理使用其提供的對象復用機制。
  • 避免不必要的對象創建,如使用Message.obtain()方法獲取Message對象,而不是直接創建新的Message對象。

2.1.3 Handler使用不當

        Handler發送大量消息,且消息處理不及時,導致消息對象堆積。

解決方案

  • 在Handler中處理消息時,確保及時處理并釋放消息對象。
  • 對于延時消息,要確保在Activity或View生命周期結束前取消未處理的消息。
  • 隊列優化=>重復消息過濾。
  • 隊列優化=>互斥消息取消。
  • 復用消息,使用Message.obtain()方法獲取Message對象。
  • 使用消息空閑ldleHandle

2.2、內存泄漏(Memory Leak)

        內存泄漏是指長生命周期的對象持有短生命周期對象的引用應用程序中的對象在不再需要時仍然被引用,導致垃圾回收器(Garbage Collector,GC)無法回收這些對象所占用的內存。內存泄漏會導致可用內存逐漸減少,最終可能導致應用程序崩潰(OOM)或系統變得非常緩慢。常見的內存泄露場景及解決方案:

2.2.1 靜態變量持有Activity或Context引用

        在靜態變量中持有Activity或Context的強引用,當Activity或Context不再需要時,由于靜態變量的生命周期與應用程序相同,導致這些對象無法被回收。

解決方案

  • 避免在靜態變量中持有Activity或Context的強引用。
  • 如果確實需要持有Context,考慮使用Application Context或弱引用(WeakReference)。

2.2.2 未取消的回調或監聽器

        在Activity或Fragment中注冊回調或監聽器,但未在適當的生命周期方法中取消注冊,導致Activity或Fragment被銷毀后,回調或監聽器仍持有其引用。

解決方案

  • 在Activity或Fragment的onDestroy或onDetach方法中取消所有回調和監聽器注冊。
  • 使用View的觀察者模式時,確保在View不再需要時解除觀察。

2.2.3 非靜態內部類持有外部類引用

        非靜態內部類默認持有其外部類的引用,如果非靜態內部類被長期持有(如作為靜態變量的成員),則外部類也無法被回收。

解決方案

  • 將內部類聲明為靜態內部類,并通過構造方法傳遞必要的Context或其他引用。
  • 如果內部類需要訪問外部類的成員,考慮使用弱引用持有外部類的引用。

2.2.4 Timer或Handler未正確取消

        使用Timer或Handler時,如果未正確取消定時任務或消息,當Activity或Fragment銷毀后,這些定時任務或消息仍可能持有其引用。

解決方案

  • 在Activity或Fragment的onDestroy或onDetach方法中取消所有Timer任務。
  • 對于Handler,確保在Activity或View生命周期結束前處理完所有消息,并調用handler.removeCallbacksAndMessages(null)來取消所有回調和消息。

2.2.5 Bitmap未及時回收

        在加載大圖片或處理圖片時,如果未及時回收Bitmap對象,可能導致內存泄露。

解決方案

  • 在不再需要Bitmap時,及時調用bitmap.recycle()方法回收Bitmap。
  • 使用圖片加載庫(如Glide、Picasso)時,這些庫通常會自動管理Bitmap的回收,但仍需注意避免在Activity或Fragment銷毀后繼續加載圖片。

2.2.6 資源文件未關閉

        在處理文件、數據庫連接等資源時,如果未正確關閉這些資源,也可能導致內存泄露。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896870.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896870.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896870.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ffmpeg源碼編譯支持cuda

1.安裝cuda CUDA Toolkit 11.3 Downloads | NVIDIA Developer 在選擇組件的時候,將CUDA中的Nsight VSE和Visual Studio Integration取消勾選 不然會安裝失敗 2.編譯ffmpeg 把cuda編譯宏定義開啟,再編譯avcodec 3.編譯livavutil報錯struct "Cuda…

Git強制覆蓋分支:將任意分支完全恢復為main分支內容

Git強制覆蓋分支:將任意分支完全恢復為main分支內容 場景背景完整操作步驟一、前置準備二、操作流程步驟 1:更新本地 main 分支步驟 2:強制重置目標分支步驟 3:強制推送至遠程倉庫 三、操作示意圖 關鍵風險提示(必讀&a…

【Java反序列化測試】

Java反序列化測試 1. 識別反序列化入口點2. 構造探測Payload3. 發送Payload并觀察結果4. 繞過可能的防護5. 自動化工具注意事項總結 Java反序列化測試: 1. 識別反序列化入口點 常見入口: HTTP請求參數(如POST數據、Cookie、Headers&#xff…

golang的io

https://www.bilibili.com/list/BV1gx4y1r7xb 1. 原生io包 io包是Go語言標準庫中底層的I/O接口層,定義了通用的讀寫規則和錯誤處理邏輯。每次讀寫都是直接調用底層系統 I/O,每次讀取1字節,系統調用次數多。適用于小數據量、實時性要求高。io…

【北京迅為】iTOP-RK3568OpenHarmony系統南向驅動開發-第4章 UART基礎知識

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工藝,搭載一顆四核Cortex-A55處理器和Mali G52 2EE 圖形處理器。RK3568 支持4K 解碼和 1080P 編碼,支持SATA/PCIE/USB3.0 外圍接口。RK3568內置獨立NPU,可用于輕量級人工…

【計算機網絡入門】初學計算機網絡(十)(重要)

目錄 1. 網絡層的作用 2. IPV4 2.1 IP 數據報格式 2.2 IP地址分類方案 2.3 數據的轉發 2.4 特殊用途的IP地址 3. 子網劃分和子網掩碼 3.1 子網劃分 3.2 子網掩碼 1. 網絡層的作用 按照教學五層模型,應用層、傳輸層、網絡層、數據鏈路層、物理層&#xff…

機器學習(五)

一,多類(Multiclass) 多類是指輸出不止有兩個輸出標簽,想要對多個種類進行分類。 Softmax回歸算法: Softmax回歸算法是Logistic回歸在多類問題上的推廣,和線性回歸一樣,將輸入的特征與權重進行…

基于 Vue 和 SSM 的前后端分離項目實戰:登錄與注冊功能實現

文章目錄 前言項目概述前端部分(Vue)1. 項目初始化2. 頁面布局Login.vueRegister.vue 3. 路由配置4. 主組件 后端部分(SSM)1. 項目結構2. 數據庫設計3. MyBatis 配置4. DAO 層5. Service 層6. Controller 層7. 配置文件8. Spring …

Windows安裝nvm【超詳細圖解】

目錄 前言 一、NVM下載 方式一:官網下載 方式二:GitHub 下載 二、NVM安裝 鏡像源配置 三、Node安裝 四、環境變量配置 前言 NVM(Node Version Manager)是一個命令行工具,用于在一臺計算機上輕松管理和切換多…

KVM虛擬機磁盤創建探究-2

使用 virt-install 命令自動創建磁盤鏡像和使用 qemu-img 手動創建磁盤鏡像,在磁盤鏡像本身格式和基本功能上是一致的,但在一些特性如初始占用磁盤空間、創建時的可配置性等方面存在區別,下面以 QCOW2 格式磁盤鏡像為例進行詳細說明。 初始占…

京準電鐘:NTP校時服務器于安防監控系統應用方案

京準電鐘:NTP校時服務器于安防監控系統應用方案 京準電鐘:NTP校時服務器于安防監控系統應用方案 NTP校時服務器在安防監控系統中的應用方案主要通過高精度時間同步技術,解決設備間時間差異問題,確保日志、錄像等數據的時間一致性…

遞歸遍歷目錄 和 普通文件的復制 [Java EE]

遞歸遍歷目錄 首先 先列出當前目錄所包含的內容 File[] files currentDir.listFiles();if (files null || files.length 0) {// 若是空目錄或非法目錄, 則直接返回return;} 然后 遍歷列出的文件, 分情況兩種討論 for (File f: files) {// 加個日志, 方便查看程序執行情…

NO.19十六屆藍橋杯模擬賽第三期上

1 如果一個數 p 是個質數&#xff0c;同時又是整數 a 的約數&#xff0c;則 p 稱為 a 的一個質因數。 請問&#xff0c; 2024 的最大的質因數是多少&#xff1f; 答&#xff1a;23 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false)…

Linux網絡_應用層自定義協議與序列化_守護進程

一.協議 協議是一種 "約定". socket api 的接口, 在讀寫數據時, 都是按 "字符串" 的方式來發送接 收的. 如果我們要傳輸一些 "結構化的數據" 怎么辦呢? 其實&#xff0c;協議就是雙方約定好的結構化的數據 像下面&#xff0c;兩端都知道數據結構…

SQL命令詳解之多表查詢(連接查詢)

目錄 1 簡介 2 內連接查詢 2.1 內連接語法 2.2 內連接練習 3 外連接查詢 3.1 外連接語法 3.2 外連接練習 4 總結 1 簡介 連接的本質就是把各個表中的記錄都取出來依次匹配的組合加入結果集并返回給用戶。我們把 t1 和 t2 兩個表連接起來的過程如下圖所示&#xff1a; …

001-碼云操作

碼云操作 一、配置公鑰1.官網地址1.進入 git bash2.查看生成的公鑰3.設置到 Gitee4.測試 二、初始化一個項目1.新建倉庫 一、配置公鑰 方便后續提交代碼不用填寫密碼 1.官網地址 官網地址&#xff1a;https://gitee.com/Git碼云教程&#xff1a;https://gitee.com/help/arti…

30.[前端開發-JavaScript基礎]Day07-數組Array-高階函數-日期Date-DOM

JavaScript的DOM操作 &#xff08;一&#xff09; 1 什么是DOM&#xff1f; 認識DOM和BOM 深入理解DOM 2 認識DOM Tree DOM Tree的理解 3 DOM的整體結構 DOM的學習順序 DOM的繼承關系圖 document對象 4 節點、元素導航 節點&#xff08;Node&#xff09;之間的導航&…

【自學筆記】Spring基礎知識點總覽-持續更新

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 Spring 基礎知識點總覽1. Spring 框架簡介2. IoC&#xff08;控制反轉&#xff09;與 DI&#xff08;依賴注入&#xff09;2.1 IoC 容器2.2 依賴注入方式示例代碼&a…

WordPress多語言插件GTranslate

GTranslate是一個免費的WordPress多語言插件&#xff0c;它允許您將網站內容翻譯成多種語言。這個插件提供了一個簡單易用的界面&#xff0c;讓您可以在WordPress后臺直接進行翻譯操作。以下是GTranslate插件的一些主要特點&#xff1a; 免費使用&#xff1a;GTranslate插件完…

數列極限入門習題

數列極限入門習題 lim ? n → ∞ ( 1 1 2 1 3 ? 1 n ) 1 n \lim\limits_{n\rightarrow\infty}(1 \frac{1}{2}\frac{1}{3}\cdots\frac{1}{n})^{\frac{1}{n}} n→∞lim?(121?31??n1?)n1? lim ? n → ∞ ( 1 n 1 1 n 2 ? 1 n n ) \lim\limits_{n\rightarrow\…