日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android下常见的内存泄露

發(fā)布時(shí)間:2024/10/8 Android 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android下常见的内存泄露 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)自:http://www.linuxidc.com/Linux/2011-10/44785.htm

因?yàn)?/span>Android使用Java作為開發(fā)語言,很多人在使用會(huì)不注意內(nèi)存的問題。

于是有時(shí)遇到程序運(yùn)行時(shí)不斷消耗內(nèi)存,最終導(dǎo)致OutOfMemery,程序異常退出,這就是內(nèi)存泄露導(dǎo)致的。

我們現(xiàn)在就來總結(jié)一下可能導(dǎo)致內(nèi)存泄露的情況:

  • 查詢數(shù)據(jù)庫而沒有關(guān)閉Cursor

    在Android中,Cursor是很常用的一個(gè)對(duì)象,但在寫代碼是,經(jīng)常會(huì)有人忘記調(diào)用close, 或者因?yàn)榇a邏輯問題狀況導(dǎo)致close未被調(diào)用。


    通常,在Activity中,我們可以調(diào)用startManagingCursor或直接使用managedQuery讓Activity自動(dòng)管理Cursor對(duì)象。
    但需要注意的是,當(dāng)Activity介紹后,Cursor將不再可用!
    若操作Cursor的代碼和UI不同步(如后臺(tái)線程),那沒需要先判斷Activity是否已經(jīng)結(jié)束,或者在調(diào)用OnDestroy前,先等待后臺(tái)線程結(jié)束。

    除此之外,以下也是比較常見的Cursor不會(huì)被關(guān)閉的情況:

  • try?{??
  • ????Cursor?c?=?queryCursor();??
  • ????int?a?=?c.getInt(1);??
  • ????......??
  • ????c.close();??
  • }?catch?(Exception?e)?{??
  • }??
  • 雖然表面看起來,Cursor.close()已經(jīng)被調(diào)用,但若出現(xiàn)異常,將會(huì)跳過close(),從而導(dǎo)致內(nèi)存泄露。

    所以,我們的代碼應(yīng)該以如下的方式編寫:

  • Cursor?c?=?queryCursor();??
  • try?{??????
  • ????int?a?=?c.getInt(1);??
  • ????......??
  • }?catch?(Exception?e)?{??
  • }?finally?{??
  • ????c.close();?//在finally中調(diào)用close(),?保證其一定會(huì)被調(diào)用???
  • }??
  • 調(diào)用registerReceiver后未調(diào)用unregisterReceiver().

    在調(diào)用registerReceiver后,若未調(diào)用unregisterReceiver,其所占的內(nèi)存是相當(dāng)大的。
    而我們經(jīng)常可以看到類似于如下的代碼:

  • registerReceiver(new?BroadcastReceiver()?{??
  • ????...??
  • },?filter);?...??
  • 這是個(gè)很嚴(yán)重的錯(cuò)誤,因?yàn)樗鼤?huì)導(dǎo)致BroadcastReceiver不會(huì)被unregister而導(dǎo)致內(nèi)存泄露。


  • 未關(guān)閉InputStream/OutputStream

    在使用文件或者訪問網(wǎng)絡(luò)資源時(shí),使用了InputStream/OutputStream也會(huì)導(dǎo)致內(nèi)存泄露


  • Bitmap使用后未調(diào)用recycle()

    根據(jù)SDK的描述,調(diào)用recycle并不是必須的。但在實(shí)際使用時(shí),Bitmap占用的內(nèi)存是很大的,所以當(dāng)我們不再使用時(shí),盡量調(diào)用recycle()以釋放資源。


  • Context泄露

    這是一個(gè)很隱晦的內(nèi)存泄露的情況。
    先讓我們看一下以下代碼:
  • private?static?Drawable?sBackground;??
  • ??
  • @Override??
  • protected?void?onCreate(Bundle?state)?{??
  • ??super.onCreate(state);??
  • ????
  • ??TextView?label?=?new?TextView(this);??
  • ??label.setText("Leaks?are?bad");??
  • ????
  • ??if?(sBackground?==?null)?{??
  • ????sBackground?=?getDrawable(R.drawable.large_bitmap);??
  • ??}??
  • ??label.setBackgroundDrawable(sBackground);??
  • ????
  • ??setContentView(label);??
  • }??
  • 在這段代碼中,我們使用了一個(gè)static的Drawable對(duì)象。
    這通常發(fā)生在我們需要經(jīng)常調(diào)用一個(gè)Drawable,而其加載又比較耗時(shí),不希望每次加載Activity都去創(chuàng)建這個(gè)Drawable的情況。
    此時(shí),使用static無疑是最快的代碼編寫方式,但是其也非常的糟糕。
    當(dāng)一個(gè)Drawable被附加到View時(shí),這個(gè)View會(huì)被設(shè)置為這個(gè)Drawable的callback (通過調(diào)用Drawable.setCallback()實(shí)現(xiàn))。
    這就意味著,這個(gè)Drawable擁有一個(gè)TextView的引用,而TextView又擁有一個(gè)Activity的引用。
    這就會(huì)導(dǎo)致Activity在銷毀后,內(nèi)存不會(huì)被釋放。

    總結(jié)

    以上是生活随笔為你收集整理的Android下常见的内存泄露的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。