成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

內存泄露從入門到精通三部曲之常見原因與用戶實踐

移動開發
一般我們所說的內存泄漏有哪些原因,具體到用戶體驗階段會有什么樣的問題?

常見原因

1.集合類

集合類如果僅僅有添加元素的方法,而沒有相應的刪除機制,導致內存被占用。如果這個集合類是全局性的變量 (比如類中的靜態屬性,全局性的 map 等即有靜態引用或 final 一直指向它),那么沒有相應的刪除機制,很可能導致集合所占用的內存只增不減。

2.單例模式

不正確使用單例模式是引起內存泄露的一個常見問題,單例對象在被初始化后將在 JVM 的整個生命周期中存在(以靜態變量的方式),如果單例對象持有外部對象的引用,那么這個外部對象將不能被 JVM 正?;厥?,導致內存泄露

3.Android組件或特殊集合對象的使用

BraodcastReceiver,ContentObserver,FileObserver,Cursor,Callback等在 Activity onDestroy 或者某類生命周期結束之后一定要 unregister 或者 close 掉,否則這個 Activity 類會被 system 強引用,不會被內存回收。

不要直接對 Activity 進行直接引用作為成員變量,如果不得不這么做,請用 private WeakReference mActivity 來做,相同的,對于Service 等其他有自己聲明周期的對象來說,直接引用都需要謹慎考慮是否會存在內存泄露的可能。

4. Handler

要知道,只要 Handler 發送的 Message 尚未被處理,則該 Message 及發送它的 Handler 對象將被線程 MessageQueue 一直持有。由于 Handler 屬于 TLS(Thread Local Storage) 變量, 生命周期和 Activity 是不一致的。因此這種實現方式一般很難保證跟 View 或者 Activity 的生命周期保持一致,故很容易導致無法正確釋放。如上所述,Handler 的使用要尤為小心,否則將很容易導致內存泄露的發生。

5.Thread 內存泄露

線程也是造成內存泄露的一個重要的源頭。線程產生內存泄露的主要原因在于線程生命周期的不可控。比如線程是 Activity 的內部類,則線程對象中保存了 Activity 的一個引用,當線程的 run 函數耗時較長沒有結束時,線程對象是不會被銷毀的,因此它所引用的老的 Activity 也不會被銷毀,因此就出現了內存泄露的問題。

6.一些不良代碼造成的內存壓力

有些代碼并不造成內存泄露,但是它們,或是對沒使用的內存沒進行有效及時的釋放,或是沒有有效的利用已有的對象而是頻繁的申請新內存。

6.1 Bitmap 沒調用 recycle(). Bitmap 對象在不使用時,我們應該先調用 recycle() 釋放內存,然后才它設置為 null. 因為加載 Bitmap 對象的內存空間,一部分是 java 的,一部分 C 的(因為 Bitmap 分配的底層是通過 JNI 調用的 )。 而這個 recyle() 就是針對 C 部分的內存釋放。

6.2 構造 Adapter 時,沒有使用緩存的 convertView。


以業務測試過程中常見的部分內存泄露實例來說明:

1. callback只有add操作,沒有注銷remove

 

從引用關系可以看到當前 view 被 callback 引用,而 callback 被外部對象 sharkprotocolQueue 持有引用而導致泄漏。

2. 發送延時消息時,如果該消息未處理,在退出頁面后會導致該頁面無法回收。

Android 應用啟動的時候會創建 UI 主線程的 Looper 對象,它存在于整個應用的生命周期,用于處理消息隊列里的 Message。而這些 Message 會引用發送該消息的 Handler 對象。

那么問題來了,如果這些 Handler 是 Activity 的內部類,那么當這些 Handler 的消息未處理完或者消息本身是延時消息的話,就會導致 Activity 退出后,從 Activity 到 Handler 到 Message 到 Looper 的引用鏈條一直存在,從而導致 Activity 的泄露!

3. 異步線程未完成前退出 Activity 等組件,可能會導致界面資源無法釋放。

這種情況是典型的線程對象導致的內存泄露。原因也很簡單,線程 Thread 對象的 run 任務未執行完之前,對象本身是不會釋放的。因此 Activity 等組件對象內的線程對象成員如果有耗時任務(一般也都是耗時任務),就會導致一直持有組件本身的引用內存泄露!

本文部分內容和經驗摘自網絡,結合本次內存泄露的排查總結予以歸納。


優秀實踐

  1. 對activity等組件的引用應該控制在activity的生命周期之內; 如果不能就考慮使用 getApplicationContext或者getApplication,以避免activity被外部長生命周期的對象引用而泄露

  2. 在代碼復審的時候關注長生命周期對象:全局性的集合、單例模式的使用、類的static變量等等。

  3. 盡量不要在靜態變量或者靜態內部類中使用非靜態外部成員變量(包括context),即使要使用,也要考慮適時把外部成員變量置空;也可以在內部類中使用弱引用來引用外部類的變量;

  4. Handler的持有的引用對象***使用弱引用,資源釋放時也可以清空Handler里面的消息。比如在Activity onStop或者onDestroy的時候,取消掉該Handler對象的Message和Runnable:

  5. removeCallbacks(Runnable r)或removeMessages(int what),或removeCallbacksAndMessages(null)等。

  6. 線程Runnable執行耗時操作,注意在頁面返回時及時取消或者把Runnable寫成靜態類。 a) 如果線程類是內部類,改為靜態內部類。 b) 線程內如果需要引用外部類對象如context,需要使用弱引用。

  7. 在Java的實現過程中,也要考慮其對象釋放,***的方法是在不使用某對象時,顯式地將此對象賦空,如清空對圖片等資源有直接引用或者間接引用的數組(使用array.clear();array = null),***遵循誰創建誰釋放的原則。


騰訊Bugly簡介

Bugly是騰訊內部產品質量監控平臺的外發版本,其主要功能是App發布以后,對用戶側發生的Crash以及卡頓現象進行監控并上報,讓開發同學可以***時間了解到App的質量情況,及時機型修改。目前騰訊內部所有的產品,均在使用其進行線上產品的崩潰監控。

責任編輯:倪明 來源: 騰訊Bugly
相關推薦

2015-11-18 09:28:44

內存泄露入門

2015-11-09 11:48:20

內存泄漏基礎知識

2009-09-14 09:04:17

CCNA考試CCNA

2011-03-25 09:56:40

Nagios 安裝

2011-03-09 09:30:52

Mina

2011-03-28 16:52:08

用戶體驗Android

2010-07-17 01:12:31

Telnet服務

2010-09-26 14:39:40

DHCP故障分析

2011-08-03 10:33:05

網絡管理網絡拓撲管理

2013-06-28 09:35:04

Hypervisor虛擬化成本

2010-09-06 09:22:26

CSS語法

2011-03-21 09:22:46

Tomcat

2022-10-10 09:10:51

家庭網絡網絡

2019-03-28 14:45:33

數據安全數據泄露信息安全

2017-02-07 14:50:39

華為

2017-04-11 09:07:20

互聯網

2015-05-12 10:42:53

程序員代碼

2012-09-10 16:19:00

云計算公共云

2010-09-14 16:54:18

2018-03-18 15:51:59

人工智能潛力首席數據官
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩国产精品一区 | 国产精品女人久久久 | 国产精品中文字幕在线 | 日日夜夜精品免费视频 | 日日天天| 日韩一区二区av | 亚洲一区二区高清 | 日韩三片 | 成人h电影在线观看 | 黄色网络在线观看 | 欧美一区二区免费 | 毛片免费在线 | 青青草av在线播放 | 我想看国产一级毛片 | 欧美一级黄色片 | 中文字幕一区二区在线观看 | 国内精品视频在线观看 | 欧美日韩一区二区三区四区 | 国产精品不卡 | 99国内精品久久久久久久 | 欧美国产视频 | 亚洲成人av| 成人av一区 | 91麻豆精品国产91久久久久久 | 日韩一级电影免费观看 | 四虎影院在线观看免费视频 | 九九九久久国产免费 | 精品国产乱码久久久久久闺蜜 | 欧美在线观看一区 | 日本午夜在线视频 | 在线观看中文字幕av | 拍戏被cao翻了h承欢 | 久久综合伊人 | 伊人春色在线 | 欧美一级毛片在线播放 | 亚洲色视频 | 91麻豆精品国产91久久久资源速度 | 国产精品美女久久久久久久久久久 | 国产精品视频二区三区 | 欧美中文| 狠狠操电影 |