作者:不洗碗工作室fhyPayaso
版權歸作者所有,轉載請註明出處
1. Java中物件和物件引用的區別
先看一個例子 :
Person person;
person = new Person("name");複製程式碼
上面兩行程式碼中,第一行person屬於宣告瞭一個Person類的引用,而第二行的new才是真正建立了一個物件。
2.Java中的記憶體環境
Java在JVM所虛擬的記憶體環境中執行,記憶體可以分為三個部分:棧,堆,方法區
-
棧(stack) 每一個執行緒都擁有一個棧,在這裡只儲存基本資料型別和物件的引用(注意和物件的區別),例如在方法中定義一個區域性變數,就會在棧中給這個變數分配記憶體空間,超過該變數的作用域時,這部分記憶體就會被回收掉。
-
堆(heap) 被所有程式所共享,只存放陣列、物件以及物件的成員變數,不包括基本型別和引用,這部分記憶體空間由java中的垃圾回收機制自動管理。
-
方法區(method) 又叫靜態區,同樣被所有程式所共享,存放class和static變數。
舉個例子:
public class Person {
int age = 18;
Person personA = new Person();
public void method() {
int height = 180;
Person personB = new Person();
}
}
Person personC = new Person();複製程式碼
在上面的例子中,height以及引用變數personB都屬於區域性變數,所以它們的記憶體應存放在棧中,在method方法之外的作用域,這部分記憶體就會被回收,而personB所指向的物件的記憶體存放在堆上。 引用變數personC所指向的物件同理也存放在堆上,當然也包括Person類的成員變數age和personA,但引用變數personC本身則是存放在棧中。
3.垃圾回收機制(GC)
在Java中,記憶體的分配是由程式來完成的,而記憶體的回收則是由GC完成的,GC為了能正確的釋放物件,必須監控每一個物件的執行狀態,包括物件的申請、引用、賦值等。物件通過引用的方式來使用,而當一個物件沒有任何引用的時候,稱為不可到達物件,GC用於回收不可到達物件所佔用的記憶體。
4.安卓中的記憶體洩露
雖然java中有垃圾回收的機制,可以自動管理記憶體分配,但是仍有可能出現記憶體洩露的情況。Java作為Android的主要開發語言,當存在記憶體洩漏時,APP就會浪費大量記憶體,當記憶體不夠時會導致頻繁的記憶體回收,然而記憶體回收是十分耗時的操作,這樣就會導致APP的卡頓,嚴重的可能會導致記憶體溢位,退出程式。
-
記憶體洩露的原因 安卓中主要出現記憶體洩漏的原因本質上就是,一個物件已經不會再被使用,但其記憶體卻沒有被系統所回收,而無法被回收的原因一般是由於該物件被一個生命週期更長的物件所引用。
-
常見的記憶體洩漏
-
static關鍵字所導致的記憶體洩露
舉個例子:
public class MainActivity extends Activity{ private static Context context; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R,layout.main); context = this; } }複製程式碼
context為靜態變數,生命週期較長,導致當前activity被銷燬後無法被系統回收,產生記憶體洩漏。
解決辦法:在Activity的onDestroy方法裡把靜態變數設為null
protected void onDestroy() { super.onDestroy(); if(context != null) { context = null; } }複製程式碼
-
本文先初步探究android中的記憶體洩露的基本原理,其他具體可能引起記憶體洩露的情景和解決方法會在後續文章中探討。
參考文章: 《Android 中記憶體洩漏的原因和解決方案》http://m.blog.csdn.net/lib739449500/article/details/78741263 《Android常見記憶體洩露,學會這六招大大優化APP效能》https://www.douban.com/note/609777758/