Android面試題之記憶體溢出和記憶體流失的問題

來源:互聯網
上載者:User

標籤:記憶體流失   影像處理   注意   多少   系統   壓縮   markdown   手機   err   

在面試中,經常有面試官會問“你知道什麼是記憶體溢出?什麼是記憶體流失?怎麼避免?”通過這篇文章,你可以回答出來了。

記憶體溢出 (OOM)是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如只申請了一個integer,但給它存了long才能存下的數,那就會出現記憶體溢出。

記憶體泄露 (memory leak)是指程式在申請記憶體後,無法釋放已申請的記憶體空間,一次記憶體泄露危害可以忽略,但記憶體泄露堆積後果很嚴重,無論多少記憶體,遲早會被佔光。

記憶體流失最終會導致記憶體溢出。

如何避免記憶體溢出?

強引用:強引用是使用最普遍的引用。如果一個對象具有強引用,那記憶體回收行程絕不會回收它。 當記憶體空間不足,Java虛擬機器寧願拋出OutOfMemoryError錯誤,使程式異常終止,也不會靠隨意回收具有強引用的對象來解決記憶體不足的問題。
軟引用:如果一個對象只具有軟引用,但記憶體空間足夠時,記憶體回收行程就不會回收它;直到虛擬機器報告記憶體不夠時才會回收, 只要記憶體回收行程沒有回收它,該對象就可以被程式使用。軟引用可用來實現記憶體敏感的快取。 軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被記憶體回收行程回收,Java虛擬機器就會把這個軟引用加入到與之關聯的引用隊列中。
弱引用:只具有弱引用的對象擁有更短暫的生命週期。在記憶體回收行程線程掃描它所管轄的記憶體地區的過程中,一旦發現了只具有弱引用的對象,不管當前記憶體空間是否足夠,都會回收它的記憶體。 不過,由於記憶體回收行程是一個優先順序很低的線程,因此不一定會很快發現那些只具有弱引用的對象。 弱引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果弱引用所引用的對象被記憶體回收,Java虛擬機器就會把這個弱引用加入到與之關聯的引用隊列中。
虛引用:虛引用可以理解為虛設的引用,與其他幾種引用都不同,虛引用並不會決定對象的生命週期。如果一個對象僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被記憶體回收行程回收。 虛引用主要用來跟蹤對象被記憶體回收行程回收的活動。 虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用隊列 (ReferenceQueue)聯合使用。 當記憶體回收行程準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的記憶體之前,把這個虛引用加入到與之 關聯的引用隊列中。 程式可以通過判斷引用隊列中是否已經加入了虛引用,來瞭解被引用的對象是否將要被記憶體回收。 如果程式發現某個虛引用已經被加入到引用隊列,那麼就可以在所引用的對象的記憶體被回收之前採取必要的行動。

1,釋放強引用,使用軟引用和弱引用;

2,影像處理
大部分的OOM都是發生在圖片載入上的,當我們載入大圖時,需要特別注意避免OOM的發生。
處理大圖片時,不管你的手機記憶體有多大,如果不對圖片進行處理,都有可能會發生記憶體溢出問題。
1、在記憶體中壓縮圖片
裝載大圖片時需要對圖片進行壓縮,使用等比例壓縮的方法直接在記憶體中處理圖片

Options options = new BitmapFactory.Options(); options.inSampleSize = 5; // 原圖的五分之一,設定為2則為二分之一 BitmapFactory.decodeFile(myImage.getAbsolutePath(), options); 

這樣做要注意的是,圖片品質會變差,inSampleSize設定的值越大,圖片品質就越差,不同的手機廠商縮放的比例可能不同。
2、使用完圖片後回收圖片所佔記憶體
由於Android外層是使用java而底層使用的是C語言在裡層為圖片對象分配的記憶體空間。
所以我們的外部雖然看起來釋放了,但裡層卻並不一定完全釋放了,我們使用完圖片後最好再釋放掉裡層的記憶體空間。

if (!bitmapObject.isRecyled()) {     // Bitmap對象沒有被回收      bitmapObject.recycle();     // 釋放      System.gc();     // 提醒系統及時回收 }  

3、降低要顯示的圖片色彩品質
Android中Bitmap有四種圖片色彩模式:
ALPHA_8:每個像素需要佔用記憶體中的1byte
RGB_565:每個像素需要佔用記憶體中的2byte
ARGB_4444:每個像素需要佔用記憶體中的2byte
ARGB_8888:每個像素需要佔用記憶體中的4byte
我們建立Bitmap時,預設的色彩模式是ARGB_8888的,這種色彩模式是品質最高的,當然這樣的模式佔用的記憶體也最大。
而ARGB_4444每個像素只佔用2byte,所以使用ARGB_4444的模式也能降低圖片佔用的記憶體大小。

4、查詢圖片資訊時不把圖片載入到記憶體中
有時候我們取得一張圖片,也許只是為了獲得這個圖片的一些資訊,比片的width、height等資訊,不需要顯示到介面上,這個時候我們可以不把圖片載入到記憶體中。

BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 不把圖片載入到記憶體中 Bitmap btimapObject = BitmapFactory.decodeFile(myImage.getAbsolutePath(), options);  

我們不應該把解決OOM的問題寄託在爭取最大的記憶體上,應該通過合理的代碼編寫來儘可能的規避OOM問題。

如何避免記憶體流失?
1,在 onDestroy()方法中顯示調用mThread.close();以此來結束該線程,這就避免了線程的記憶體流失問題。
2,使用application context 代替activity context;
3,資來源物件沒關閉造成的記憶體流失,如Cursor沒有close掉;
4,Bitmap記得recycle掉;
5,構造Adapter時,沒有使用緩衝的convertView。

Android面試題之記憶體溢出和記憶體流失的問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.