androidcontext內存
1. android static變數為什麼會導致內存溢出
Android 內存溢出的原因和解決方案如下: 1.Android的虛擬機是基於寄存器的Dalvik,它的最大堆大小一般是16M,有的機器為24M.因此我們所能利用的內存空間是有限的.如果我們的內存佔用超過了一定的水平就會出現OutOfMemory的錯誤.原因主要有兩個: l 由於我們程序的失誤,長期保持某些資源(如Context)的引用,造成內存泄露,資源造成得不到釋放. l 保存了多個耗用內存過大的對象(如Bitmap),造成內存超出限制. 2. Static static是java中的一個關鍵字,當用它來修飾成員變數時,那麼該變數就屬於該類,而不是該類的實例.所以用static修飾的變數,它的生命周期是很長的,如果用它來引用一些資源耗費過多的實例(Context的情況最多)就要謹慎對待了.例如xxx源碼: public class IntentMapping { private static Contextcontext; //. . . }
2. android 內存泄露 會導致什麼問題
1. 查詢資料庫而沒有關閉Cursor
在Android中,Cursor是很常用的一個對象,但在寫代碼是,經常會有人忘記調用close, 或者因為代碼邏輯問題狀況導致close未被調用。
通常,在Activity中,我們可以調用startManagingCursor或直接使用managedQuery讓Activity自動管理Cursor對象。
但需要注意的是,當Activity介紹後,Cursor將不再可用!
若操作Cursor的代碼和UI不同步(如後台線程),那沒需要先判斷Activity是否已經結束,或者在調用OnDestroy前,先等待後台線程結束。
除此之外,以下也是比較常見的Cursor不會被關閉的情況:
雖然表面看起來,Cursor.close()已經被調用,但若出現異常,將會跳過close(),從而導致內存泄露。
所以,我們的代碼應該以如下的方式編寫:
Cursor c = queryCursor();
try {
int a = c.getInt(1);
......
} catch (Exception e) {
} finally {
c.close(); //在finally中調用close(), 保證其一定會被調用
}
try {
Cursor c = queryCursor();
int a = c.getInt(1);
......
c.close();
} catch (Exception e) {
}
2. 調用registerReceiver後未調用unregisterReceiver().
在調用registerReceiver後,若未調用unregisterReceiver,其所佔的內存是相當大的。
而我們經常可以看到類似於如下的代碼:
這是個很嚴重的錯誤,因為它會導致BroadcastReceiver不會被unregister而導致內存泄露。
registerReceiver(new BroadcastReceiver() {
...
}, filter); ...
3. 未關閉InputStream/OutputStream
在使用文件或者訪問網路資源時,使用了InputStream/OutputStream也會導致內存泄露
4. Bitmap使用後未調用recycle()
根據SDK的描述,調用recycle並不是必須的。但在實際使用時,Bitmap佔用的內存是很大的,所以當我們不再使用時,盡量調用recycle()以釋放資源。
5. Context泄露
這是一個很隱晦的內存泄露的情況。
先讓我們看一下以下代碼:
在這段代碼中,我們使用了一個static的Drawable對象。
這通常發生在我們需要經常調用一個Drawable,而其載入又比較耗時,不希望每次載入Activity都去創建這個Drawable的情況。
此時,使用static無疑是最快的代碼編寫方式,但是其也非常的糟糕。
當一個Drawable被附加到View時,這個View會被設置為這個Drawable的callback (通過調用Drawable.setCallback()實現)。
這就意味著,這個Drawable擁有一個TextView的引用,而TextView又擁有一個Activity的引用。
這就會導致Activity在銷毀後,內存不會被釋放。
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);
}
3. 如何定位和解決Android的內存溢出問題(大總
一、定位內存泄漏:
可以用LeakCanary:檢測所有的內存泄漏
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0509/2854.html
二、解決:
1.對各種流,文件資源這些比如:InputStream/OutputStream,SQLiteOpenHelper,SQLiteDatabase,Cursor,文件,I/O,Bitmap圖片等操作等都應該記得顯示關閉。
2.盡量避免static成員變數引用資源耗費過多的實例,比如Context。因為Context的引用超過它本身的生命周期,會導致Context泄漏。所以盡量使用Application這種Context類型。
3.使用線程池,不要newthread
4.UI視圖檢查,減少視圖層級(hierarchyviewer)。
5.圖片優化
6. 重用系統資源:系統定義id,系統圖片,系統布局,系統style,系統字元串,系統顏色定義
4. android為什麼要內存優化
android為什麼要內存優化是為了防止Android的內存溢出
Android的內存溢出是如何發生的?
Android的虛擬機是基於寄存器的Dalvik,它的最大堆大小一般是16M,有的機器為24M。因此所能利用的內存空間是有限的。如果內存佔用超過了一定的水平就會出現OutOfMemory的錯誤。
為什麼會出現內存不夠用的情況呢?原因主要有兩個:由於程序的失誤,長期保持某些資源(如Context)的引用,造成內存泄露,資源造成得不到釋放。
保存了多個耗用內存過大的對象(如Bitmap),造成內存超出限制。
在android的開發中,要時刻主要內存的分配和垃圾回收,因為系統為每一個dalvik虛擬機分配的內存是有限的,在google的G1中,分配的最大堆大小隻有16M,後來的機器一般都為24M,實在是少的可憐。這樣就需要在開發過程中要時刻注意。不要因為自己的代碼問題而造成OOM錯誤。
Android的優化方式
Android的程序由Java語言編寫,所以Android的內存管理與Java的內存管理相似。程序員通過new為對象分配內存,所有對象在java堆內分配空間;然而對象的釋放是由垃圾回收器來完成的。C/C++中的內存機制是「誰污染,誰治理」,java的就比較人性化了,給我們請了一個專門的清潔工(GC)。
那麼GC怎麼能夠確認某一個對象是不是已經被廢棄了呢?Java採用了有向圖的原理。Java將引用關系考慮為圖的有向邊,有向邊從引用者指向引用對象。線程對象可以作為有向圖的起始頂點,該圖就是從起始頂點開始的一棵樹,根頂點可以到達的對象都是有效對象,GC不會回收這些對象。如果某個對象 (連通子圖)與這個根頂點不可達(注意,該圖為有向圖),那麼認為這個(這些)對象不再被引用,可以被GC回收