給關亨做網站的設計公司深圳關鍵詞推廣整站優(yōu)化
本人今年參加了很多面試,也有幸拿到了一些大廠的offer,整理了眾多面試資料,后續(xù)還會分享眾多面試資料。
整理成了面試系列,由于時間有限,每天整理一點,后續(xù)會陸續(xù)分享出來,感興趣的朋友可關注+收藏
文章目錄
- 1. 內存泄漏
- 2. 內存溢出
1. 內存泄漏
內存泄露是指申請了一塊內存,但沒有及時釋放,這塊內存就會一直被占用而無法被分配,這樣就出現(xiàn)了內存泄露。
(1)內存泄露的四種狀態(tài):
常發(fā)性內存泄漏: 發(fā)生泄露的代碼經常性被執(zhí)行,每次都會泄露一塊內存;
偶發(fā)性內存泄露: 發(fā)生內存泄露的代碼只有在特定環(huán)境和操作過程中才會發(fā)生;
一次性內存泄露: 發(fā)生內存泄露的代碼僅會被執(zhí)行一次,或者由于算法上的缺陷,導致總會有一塊且僅一塊內存發(fā)生泄露。例如:在類的構造函數(shù)中分配內存,在析構函數(shù)中卻沒有釋放內存,這里就僅發(fā)生一次。
隱式內存泄漏: 程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里并沒有發(fā)生內存泄漏,因為最終程序釋放了所有申請的內存。但是對于一個服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統(tǒng)的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。
(2)內存泄露實例:
單例、線程、hander都可能造成內存泄露。下面展示單例造成的內存泄露實例:
//單例需要傳入一個Context,所以這個Context的生命周期的長短至關重要:
public class AppManager {private static AppManager instance;private Context context;private AppManager(Context context) {this.context = context.getApplicationContext();// 1.這里傳入一個Application的Context:這將沒有任何問題,因為單例的 生命周期和Application的一樣長//this.context = context;// 2、傳入的是Activity的Context:當這個Context所對應的Activity退出時,由于該Context和Activity的生命周期一樣長(Activity間接繼承于Context),所以當前Activity退出時它的內存并不會被回收,因為單例對象持有該Activity的引用。 }public static AppManager getInstance(Context context) {if (instance != null) {instance = new AppManager(context);}return instance;}
}
單例的靜態(tài)特性使得單例的生命周期和應用的生命周期一樣長,這就說明了如果一個對象已經不需要使用了,而單例對象還持有該對象的引用,那么這個對象將不能被正?;厥?#xff0c;這就導致了內存泄漏。
怎樣解決呢?
可以是用對context使用軟引用或弱引用的方式進行引用。
2. 內存溢出
系統(tǒng)無法分配需要的內存,就會造成OOM.
產生原因及如何避免:
(1)圖片過大導致OOM:對圖片進行質量壓縮或尺寸壓縮
(2)對不需要的使用的資源進行釋放內存
(3)查詢數(shù)據(jù)庫沒有關閉游標
(4)在Activity生命周期onPause()、onStop()、onDestory()中適當釋放資源