android內存優化總結

2021-02-14 藍橋雲課精選

之前做過公司產品的內存優化,不過時間有一段時間了,可能記憶不全,歡迎大家添加補充,有錯誤之處也方便指出。

※1、追查內存的方法

使用lint

lint會提醒你很多使用不得當的地方,主要會集中再這麼幾個地方:

(1)handler等長周期匿名內部類的使用,具體原因下文表

(2)數據結構的優化,hashmap向稀疏數組的優化

(3)未使用的圖片資源

當然lint還會有很多很好的提醒,比如硬編碼,layout層級問題等,這裡就不說明了。

使用腳本每隔1s輸出對應包的PSS值

PSS的定義是:Proportional Set Size 實際使用的物理內存(比例分配共享庫佔用的內存);

共享內存則是:framework的代碼與資源在ram中佔有的內存。

所以PSS值除了自身應用佔有的內存外還包括共享內存中比例分配到單個應用身上的內存,所以我覺得用這個值來定義是否進行了優化是比較合適的。

使用核心然後再退出的功能,查看PSS值是否飆升或者在使用後長時間不降低下來

如果遇到飆升雖然後續能降低下來,但是依然有可能OOM,這樣我們也需要去追查是什麼原因了,看如何能夠減少內存的使用。

而內存使用長時間不降低下來肯定是因為對象使用後還被引用著導致未被銷毀,當遇到這些情況後,我們要引入下一個工具了MAT

使用MAT分析內存

http://my.oschina.net/biezhi/blog/286223,

這塊內容比較多,我也是參考博文進行分析的,具體的大家可以通過這篇文章來了解和發現內存使用情況。

※2、內存消耗過大的原因

2.1 handler,resultreceiver等生命周期較長的匿名內部類

匿名內部類會持有外部類的引用,從而導致短期就算activity退出但其實其中的activity也會被引用從而導致相關的資源未被回收。

2.2 數據結構的優化

hashmap替換成sparsearray

2.3 圖片的優化

採用緩存,圖片縮略加載基於不同手機的解析度獲取不同尺寸的圖片,必要時可以進行縮放以及色彩優化

android 色彩模式說明:

ALPHA_8:每個像素佔用1byte內存。

ARGB_4444:每個像素佔用2byte內存

ARGB_8888:每個像素佔用4byte內存

RGB_565:每個像素佔用2byte內存

Android默認的色彩模式為ARGB_8888,這個色彩模式色彩最細膩,顯示質量最高。但同樣的,佔用的內存也最大。

另外bitmap要記得recycle。

2.4 對象生命周期,這裡有如下幾點要注意

(一)開發上儘量避免內存中太多對象的存在,比如可以用資料庫來實現

(二)切勿在循環調用的地方去產生對象,比如很多人不會注意的在getview裡new onclicklistener(),這樣的方式拖動的次數越多那麼就會產生越多的對象。當然還有在onDraw的地方newPaint等操作,這些都是需要避免的。

(三)使用完對象要及時銷毀,比如能局部變量的不要使用全局變量,功能用完成後要去掉對他的引用。

(四)大內存對象長生命周期,現有的內存回收機制都是分為新生代,中生代,老年代進行回收,而老年代的回收會對性能影響頗大,所以要儘量避免這樣的對象存在。

(五)bitmap記得recycle,cursor要記得close

(六)各種監聽,廣播等,註冊後忘記取消等。

2.5 慎用service

理論上linux系統在內存充足時不會在程序退出就Kill這個進程,而是會保存進程到lrucache中從而方便下次快速啟動。

而android的幾大組件的生命周期中,前臺可見的activity優先級最高最難回收,然後前臺不可見的activity次之,service是第三,而空進程則是最容易被回收的。

如果啟動太多的service同時使用完畢後也不關係,那麼就會造成內存的佔用,即使是切換其他的程序這個service佔用的內存也很難被回收,當內存過緊時就會造成系統的不穩定。

推薦IntentService。

2.6 代碼細節注意

Enums的內存消耗通常是static constants的2倍。你應該儘量避免在Android上使用enums。

在Java中的每一個類(包括匿名內部類)都會使用大概500 bytes。

每一個類的實例花銷是12-16 bytes。

往HashMap添加一個entry需要額一個額外佔用的32 bytes的entry對象。

在已知數量大小的情況下,初始化容器時訂好容器大小,比如new arraylist(3)那麼數組就只會分配三個空間。

2.7 單例的使用

一般來說我們是不推薦用單例的,因為大家為了偷懶寫代碼更方便一個勁的整成了單例,越多的單例使用導致內存中長時間存活的對象過多,也會讓內存佔用過多。

2.8 無效的資源

包括沒有用到的圖片等資源,以及可以縮小內存的外部library,比如視頻sdk中我們使用了更小的一個。


※3、Update

3.1 非UI線程調用View的post(Runnable r)函數

匿名內部回調接口類持有view的引用,再回調時通過post(Runnable r)的方式,希望操作能夠在UI THREAD執行操作,做一些更新UI的操作,這樣就可以不要寫handler相關的邏輯,寫法簡單。

但是這樣就會造成內存洩露,當view被detach的時候,view的attachinfo為空,這個從ViewRootImpl到父View,子View一層層傳下來的attachinfo,當view被detach的時候,這個attachinfo會為空。於是Post函數執行如下操作:

ViewRootImpl.getRunQueue().post(action);

在getRunQueue中會通過靜態的sRunQueues去綁定到當前的線程中,也就是這個異步線程中,只要這個線程存在這個引用關係就會一直存在而不被釋放。

static final ThreadLocal sRunQueues = new ThreadLocal()。

※4、後續處理

其實我覺得我的方法並不是一個十分良好的方法,我也只做了核心的功能的測試和優化,而其實代碼中還有很多的地方也可以優化,但是並沒有時間和太好的方法進行優化了,所以將這些內存使用問題分享給團隊,讓每個人自查自己代碼,同時在以後開發中注意,那麼就會讓工程代碼質量更高。

如果大家有更好的追查方法,也歡迎分享給我!

via:http://www.jianshu.com/p/d9ba8573a940

作者:昱全yuquan

點擊「閱讀原文」,即可查看【Android開發不得不看的實戰小案例】



相關焦點

  • 最全的Android內存優化技巧
    作者:Geekholt地址:https://www.jianshu.com/p/51e28a2c609c前言在Android中,內存是十分寶貴的資源,內存優化有助於提高用戶的體驗,所以學習內存優化技巧是非常重要的。
  • Android性能優化--內存優化
    本文來自Dotry投稿,連結:https://www.jianshu.com/p/38b627adaecd上一篇文章關於Android性能優化--啟動優化探討了啟動優化相關的知識點,在本篇將介紹內存優化的相關優化。
  • Android性能優化:手把手帶你全面實現內存優化
    最近有想換工作的同學們,可參考《5月技術崗位內推|RN開發招聘啦》,再往下看,一篇關於性能優化的好文章,很值得去學習。前言在 Android開發中,性能優化策略十分重要本文主要講解性能優化中的內存優化,希望你們會喜歡目錄
  • Android性能優化:帶你全面實現內存優化
    此處僅總結流程,這其中的過程複雜,有興趣的讀者可研究系統源碼ActivityManagerService.java3.3 針對對象、變量的內存策略Android的對於對象、變量的內存策略同 Java內存管理 = 對象 / 變量的內存分配 + 內存釋放下面,將詳細講解內存分配 & 內存釋放策略
  • Android避免內存溢出(Out of Memory)方法總結
    絕對乾貨-國內值得關注的官方API集合,很全很強大(必須收藏)[乾貨]2017已來,最全面試總結——這些Android面試題你一定需要避免內存溢出的方法,主要是對以下三個方面對程序進行優化>在jvm報告內存不足之前會清除所有的軟引用,這樣的話gc就可以收集到很多軟引用釋放出來的內存空間,從而解決內存吃緊的問題,避免內存溢出,什麼時候被回收取決於gc的算法和gc運行時可用的內存大小。
  • Android 性能優化之內存洩漏,使用MAT&LeakCanary解決問題
    本文較長,閱讀大約5分鐘App進行到最終的測試的時候,往往會出現一些性能上,以及內存上的問題,需要優化,這也是一個Android高級工程師所需要了解並且掌握的知識點
  • Android性能優化總結
    網絡:頻繁的網絡訪問會導致耗電和影響應用的性能;網絡交互數據大小會影響網絡傳輸的效率;5. 程序執行效率:糟糕的代碼會嚴重影響程序的運行效率,UI線程過多的任務會阻塞應用的正常運行,長時間持有某個對象會導致潛在的內存洩露,頻繁的IO操作、網絡操作而不用緩存會嚴重影響程序的運行效率。
  • 幾乎是史上最全最實用的Android性能全面分析與優化方案研究
    藉助性能優化工具分析解決問題性能優化指標性能問題分類1、渲染問題: 過度繪製、布局冗雜2、內存問題: 內存浪費(內存管理)、內存洩漏3、功耗問題: 耗電性能優化原則和方法2、內存內存大小:峰值越低越好,需要優化前後做對比內存洩漏:需要用工具檢查對比優化前後3、功耗一、渲染問題先來看看造成應用UI卡頓的常見原因都有哪些?
  • android 復用 布局優化專題及常見問題 - CSDN
    在布局優化中,Androi的官方提到了這三種布局<include />、<merge />、<ViewStub />,並介紹了這三種布局各有的優勢,下面也是簡單說一下怎麼使用.
  • 高頻面試點:Android性能優化之內存優化(上篇)
    眾所周知,內存優化可以說是性能優化中最重要的優化點之一,可以說,如果你沒有掌握系統的內存優化方案,就不能說你對Android的性能優化有過多的研究與探索。本篇,筆者將帶領大家一起來系統地學習Android中的內存優化。
  • ...既然妹紙不在家,剛好最近一直在為項目做內存洩漏的優化工作,那...
    結果因為妹紙公司臨時有事,她不得不回公司一趟…然後我也只能宅家裡了,既然妹紙不在家,剛好最近一直在為項目做內存洩漏的優化工作,那就來寫一點個人總結好了。什麼是內存洩漏對於不同的語言平臺來說,進行標記回收內存的算法是不一樣的,像Android(Java)則採用GC-Root的標記回收算法。
  • 三年經驗 Android 開發面經總結
    有沒有實際的ANR定位問題的經歷5.性能優化你做過哪些?6.android跨進程通信了解嗎?共享內存用過嗎?binder怎麼驗證pid?binder驅動了解嗎?7.SharedParence可以跨進程通信嗎?如何改造成可以跨進程通信的.commit和apply的區別.
  • 探索 Android 內存優化方法
    基本介紹 在我學習 Android 多線程優化方法的過程中,發現我對多線程優化的了解太片面。寫這篇文章的目的是完善我對 Android 多線程優化方法的認識,分享這篇文章的目的是希望大家也能從這些知識從得到一些啟發。這篇文章分為下面三部分。第一部分第一部分講的是多線程優化的基礎知識,包括線程的介紹和線程調度基本原理的介紹。
  • 一次Android面試心得及面試題總結
    總結下經驗,也是對過去的一個回顧和總結吧。一、簡歷網上有很多對程式設計師簡歷的一些指導,這裡就不重述,大家可以搜下網上其他大神的總結,結合自身情況修改下。我有幾點建議:儘量不要花哨,程式設計師和設計師或者產品運營還不一樣,我們的簡歷成功與否決定權還是在技術面試官那,而他們看重的是你的項目經驗內容和技術等描述。
  • Android應用耗電量分析與優化建議
    www.jianshu.com/p/ebac88cdf9d6文章源自網絡,如果涉及侵權等問題,請第一時間聯繫我們予以下架Battery Historian工具使用Battery Historian 一款由Google提供的Android系統電量分析工具,從手機中導出bugreport文件上傳至頁面,在網頁中生成詳細的圖表數據來展示手機上各模塊電量消耗過程,最後通過App數據的分析制定出相關的電量優化的方法
  • Android開發必備的「80」個開源庫
    你所不知道的Android Studio調試技巧https://www.jianshu.com/p/011eb88f4e0d一份系統、全面的安卓進階學習指南https://github.com/iwannabetop/Awesome-Android-Learning-GuideTrinea - 性能優化系列總篇
  • Android性能優化典範
    摘要:Google在Udacity上的《Android性能優化》在線課程詳細介紹了該如何優化性能,這些課程是Google之前在Youtube上發布的Android性能優化典範專題課程的細化與補充。本文是對渲染、運算、內存、電量四個篇章的學習筆記。
  • 【Android】一次面試總結
    ,所以儘量多做一些自己的總結,針對自己的薄弱點重點說明,適當的借鑑別人,少走一些彎路。http://www.jackywang.tech/AndroidInterview-Q-A/chinese/android/%E4%BB%80%E4%B9%88%E6%83%85%E5%86%B5%E5%AF%BC%E8%87%B4%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F-%E7%BE%8E%E5%9B%A2.htmloom和內存洩漏內存洩漏:
  • 三年啦,跳槽成功的Android開發面經總結!
    有沒有實際的ANR定位問題的經歷5.性能優化你做過哪些?6.有什麼實際解決UI卡頓優化的經歷7.有做過什麼Bitmap優化的實際經驗8.項目搭建過程中有什麼經驗,有用到什麼gradle腳本,分包有做什麼操作9.組件化有詳細了解過嗎?
  • Android 網絡優化方案
    面試官:ok,看來是有備而來,那麼我們今天聊聊網絡優化咋做吧。小蝦:我大意了,沒有閃。老頭子,你不講武德,我奉勸你耗子尾汁。如何優化一個網絡請求呢?相信大家在面試的時候可能會被問到這個問題。一個Http請求在建立Tcp連接的過程中,肯定會產生一次DNS,那麼我們是不是可以通過內存緩存的方式,通過一個HashMap持有這個Host的IP,當下次發起Tcp連接的時候,我們就可以用直接用內存中的這個Ip,而不需要再去走一遍Dns服務了。這個時候你肯定會問我,臥槽,你這個不是搞我嗎,這可怎麼改呀?