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

Android內(nèi)存泄漏產(chǎn)生的6大原因

移動開發(fā) Android
資源性對象比如(Cursor,F(xiàn)ile文件等)往往都用了一些緩沖,我們在不使用的時候,應該及時關閉它們,以便它們的緩沖及時回收內(nèi)存。它們的緩沖不僅存在于 java虛擬機內(nèi),還存在于java虛擬機外。如果我們僅僅是把它的引用設置為null,而不關閉它們,往往會造成內(nèi)存泄漏。

 [[179035]]

1.資源對象沒關閉造成的內(nèi)存泄漏

描述:

資源性對象比如(Cursor,F(xiàn)ile文件等)往往都用了一些緩沖,我們在不使用的時候,應該及時關閉它們,以便它們的緩沖及時回收內(nèi)存。它們的緩沖不僅存在于 java虛擬機內(nèi),還存在于java虛擬機外。如果我們僅僅是把它的引用設置為null,而不關閉它們,往往會造成內(nèi)存泄漏。因為有些資源性對象,比如 SQLiteCursor(在析構(gòu)函數(shù)finalize(),如果我們沒有關閉它,它自己會調(diào)close()關閉),如果我們沒有關閉它,系統(tǒng)在回收它時也會關閉它,但是這樣的效率太低了。因此對于資源性對象在不使用的時候,應該調(diào)用它的close()函數(shù),將其關閉掉,然后才置為null.在我們的程序退出時一定要確保我們的資源性對象已經(jīng)關閉。

程序中經(jīng)常會進行查詢數(shù)據(jù)庫的操作,但是經(jīng)常會有使用完畢Cursor后沒有關閉的情況。如果我們的查詢結(jié)果集比較小,對內(nèi)存的消耗不容易被發(fā)現(xiàn),只有在常時間大量操作的情況下才會復現(xiàn)內(nèi)存問題,這樣就會給以后的測試和問題排查帶來困難和風險。

示例代碼:

  1. Cursor cursor = getContentResolver().query(uri...);  
  2.  
  3. if (cursor.moveToNext()) {  
  4.  
  5. ... ...  
  6.  
  7.  

修正示例代碼: 

  1. Cursor cursor = null;  
  2.  
  3. try {  
  4.  
  5. cursor = getContentResolver().query(uri...);  
  6.  
  7. if (cursor != null &&cursor.moveToNext()) {  
  8.  
  9. ... ...  
  10.  
  11. }  
  12.  
  13. } finally {  
  14.  
  15. if (cursor != null) {  
  16.  
  17. try {  
  18.  
  19. cursor.close();  
  20.  
  21. } catch (Exception e) {  
  22.  
  23. //ignore this  
  24.  
  25. }  
  26.  
  27. }  
  28.  
  29.  

2.構(gòu)造Adapter時,沒有使用緩存的convertView

描述:

以構(gòu)造ListView的BaseAdapter為例,在BaseAdapter中提供了方法:

public View getView(int position, ViewconvertView, ViewGroup parent)

來向ListView提供每一個item所需要的view對象。初始時ListView會從BaseAdapter中根據(jù)當前的屏幕布局實例化一定數(shù)量的 view對象,同時ListView會將這些view對象緩存起來。當向上滾動ListView時,原先位于最上面的list item的view對象會被回收,然后被用來構(gòu)造新出現(xiàn)的最下面的list item。這個構(gòu)造過程就是由getView()方法完成的,getView()的第二個形參View convertView就是被緩存起來的list item的view對象(初始化時緩存中沒有view對象則convertView是null)。由此可以看出,如果我們不去使用 convertView,而是每次都在getView()中重新實例化一個View對象的話,即浪費資源也浪費時間,也會使得內(nèi)存占用越來越大。 ListView回收list item的view對象的過程可以查看:

android.widget.AbsListView.java –> voidaddScrapView(View scrap) 方法。

示例代碼:

  1. public View getView(int position, ViewconvertView, ViewGroup parent) {  
  2.  
  3. View view = new Xxx(...);  
  4.  
  5. ... ...  
  6.  
  7. return view;  
  8.  
  9.  

修正示例代碼:

  1. public View getView(int position, ViewconvertView, ViewGroup parent) {  
  2.  
  3. View view = null;  
  4.  
  5. if (convertView != null) {  
  6.  
  7. view = convertView;  
  8.  
  9. populate(view, getItem(position));  
  10.  
  11. ...  
  12.  
  13. else {  
  14.  
  15. view = new Xxx(...);  
  16.  
  17. ...  
  18.  
  19. }  
  20.  
  21. return view;  
  22.  
  23.  

3.Bitmap對象不在使用時調(diào)用recycle()釋放內(nèi)存

描述:

有時我們會手工的操作Bitmap對象,如果一個Bitmap對象比較占內(nèi)存,當它不在被使用的時候,可以調(diào)用Bitmap.recycle()方法回收此對象的像素所占用的內(nèi)存,但這不是必須的,視情況而定??梢钥匆幌麓a中的注釋:

  1. /**  
  2.  
  3. Free up the memory associated with thisbitmap's pixels, and mark the  
  4.  
  5. •bitmap as "dead", meaning itwill throw an exception if getPixels() or  
  6.  
  7. •setPixels() is called, and will drawnothing. This operation cannot be  
  8.  
  9. •reversed, so it should only be called ifyou are sure there are no  
  10.  
  11. •further uses for the bitmap. This is anadvanced call, and normally need  
  12.  
  13. not be called, since the normal GCprocess will free up this memory when  
  14.  
  15. •there are no more references to thisbitmap.  
  16.  
  17. */  

4.試著使用關于application的context來替代和activity相關的context

這是一個很隱晦的內(nèi)存泄漏的情況。有一種簡單的方法來避免context相關的內(nèi)存泄漏。最顯著地一個是避免context逃出他自己的范圍之外。使用Application context。這個context的生存周期和你的應用的生存周期一樣長,而不是取決于activity的生存周期。如果你想保持一個長期生存的對象,并且這個對象需要一個context,記得使用application對象。你可以通過調(diào)用 Context.getApplicationContext() or Activity.getApplication()來獲得。更多的請看這篇文章如何避免

5.注冊沒取消造成的內(nèi)存泄漏

一些Android程序可能引用我們的Anroid程序的對象(比如注冊機制)。即使我們的Android程序已經(jīng)結(jié)束了,但是別的引用程序仍然還有對我們的Android程序的某個對象的引用,泄漏的內(nèi)存依然不能被垃圾回收。調(diào)用registerReceiver后未調(diào)用unregisterReceiver。

比如:假設我們希望在鎖屏界面(LockScreen)中,監(jiān)聽系統(tǒng)中的電話服務以獲取一些信息(如信號強度等),則可以在LockScreen中定義一個 PhoneStateListener的對象,同時將它注冊到TelephonyManager服務中。對于LockScreen對象,當需要顯示鎖屏界面的時候就會創(chuàng)建一個LockScreen對象,而當鎖屏界面消失的時候LockScreen對象就會被釋放掉。

但是如果在釋放 LockScreen對象的時候忘記取消我們之前注冊的PhoneStateListener對象,則會導致LockScreen無法被垃圾回收。如果不斷的使鎖屏界面顯示和消失,則最終會由于大量的LockScreen對象沒有辦法被回收而引起OutOfMemory,使得system_process 進程掛掉。

雖然有些系統(tǒng)程序,它本身好像是可以自動取消注冊的(當然不及時),但是我們還是應該在我們的程序中明確的取消注冊,程序結(jié)束時應該把所有的注冊都取消掉。

6.集合中對象沒清理造成的內(nèi)存泄漏

我們通常把一些對象的引用加入到了集合中,當我們不需要該對象時,并沒有把它的引用從集合中清理掉,這樣這個集合就會越來越大。如果這個集合是static的話,那情況就更嚴重了。

責任編輯:龐桂玉 來源: Android開發(fā)中文站
相關推薦

2015-07-16 10:24:37

Facebook延誤

2011-04-14 13:42:23

漏殺病毒木馬

2024-08-05 10:40:58

2013-08-07 10:16:43

Android內(nèi)存泄漏

2010-09-02 10:52:39

2013-07-03 09:54:54

Android蘋果市場份額

2020-09-11 19:38:31

GitOps倉庫CI

2012-05-14 09:20:18

移動CRM

2017-12-12 13:35:59

Linux慕尼黑放棄原因

2011-03-24 14:25:44

2011-08-27 09:26:03

投影儀技巧

2010-10-14 10:47:33

Android

2021-11-05 15:20:07

云配置錯誤云安全數(shù)據(jù)泄露

2024-05-14 15:04:04

ChatGPT人工智能大型語言模型

2018-08-15 06:52:47

2018-01-31 08:34:42

2012-04-10 09:44:15

2021-03-12 10:22:58

數(shù)據(jù)庫DBaaS云計算

2009-12-22 09:06:10

2015-04-14 11:31:35

軟件軟件招人討厭
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 男人天堂色 | 97超碰在线免费 | 国产极品车模吞精高潮呻吟 | 在线免费观看日本视频 | 日本成人中文字幕 | 欧美黄色一区 | 自拍偷拍第一页 | 一区二区三区四区免费视频 | 久久婷婷av| 九九久久精品 | 亚洲一区日韩 | 中文字幕日韩欧美 | 伊人看片 | 国产精品伦理一区二区三区 | 久www| 特级毛片 | 国产福利91精品一区二区三区 | 亚洲美乳中文字幕 | 成人日韩精品 | 亚洲xxxxx| 精品三级在线观看 | 一级片免费在线观看 | 国产欧美精品区一区二区三区 | 中文区中文字幕免费看 | www.成人免费视频 | 中文字幕男人的天堂 | 日韩在线小视频 | 国产探花在线精品一区二区 | 99re在线 | 久久久久久精 | 国产99久久久国产精品下药 | 欧美一区二区成人 | 免费在线一区二区 | 国产精品电影网 | 一区二区三区四区电影 | 在线成人av | 亚洲精品电影在线 | 二区成人 | 久久久精品一区二区三区四季av | 亚洲成人av在线 | 欧美区日韩区 |