Android——內存泄漏

1. 什麼是內存泄漏和內存溢出java

內存泄漏:能夠簡單地理解爲內存丟了,也就是說new以後忘記釋放掉了,致使內存一直在被佔用,程序沒法再使用這個內存單元,直到程序結束才能使用。這就是內存泄漏了。數據庫

內存溢出:溢出就是裝不下,漫了出來,好比爲一個變量開闢了一個int類型的空間,卻要把一個long型或float型的數據存進去,這個就是溢出。數組

屢次或者大量的內存泄漏最終會致使內存溢出,從而致使OOM(out of memory)。架構

 

2. java中的內存架構工具

圖片來源(https://my.oschina.net/xiaohui249/blog/170013)ui

下圖是JVM的結構示意圖,每當啓動一個java程序時,就會相應地建立一個虛擬機實例。this

(1) Garbage Collection:java的垃圾回收機制,主要就是負責回收堆中的對象(該對象再也不被引用)。spa

(2) Classloader Sub-System:java中的類加載系統,每個class類只會被加載器加載一次,加載主要有兩種方式(懶漢:須要的時候才加載,餓漢:首先加載完成)。加載器主要用來定位和導入二進制class文件。操作系統

(3) Execution Engine:JVM中的執行引擎,主要就是負責執行包含在加載器中方法的指令。JNI以及Native Library的存在是爲了彌補java的缺陷,java在運行速度上比C++慢許多,並且沒法訪問操做系統底層,因此native和JNI就至關與java和C之間的接口,是爲了使用C的一些程序而存在的。.net

(4) Java Memory Allocation Area:java的虛擬機內存,也就是執行時的數據區。

 

 

java的虛擬機內存又主要分爲幾個部分

(1) 堆(Heap):存放new建立的對象和數組,java的gc機制也主要是對這部分來進行操做的。JVM只有一個堆供全部的線程來共享

(2) 棧(Stack):java中的棧用來存放基本的數據類型以及對象的引用。JVM爲每個新的線程分配一個棧

(3) 方法區(Method Area):方法區包含全部的class變量以及static變量。方法區又叫作靜態區,跟堆有些相似,是被全部的線程共享的。

(4) 程序計數器(Program Count Register):程序計數器。每次有一個新線程被建立時,都會獲得一個PC寄存器(程序計數器)

(5) 本地方法棧(Native Stack):每一個線程運行時本身的本地方法棧

圖片來源(https://my.oschina.net/xiaohui249/blog/170013)

 

3. 爲何會產生內存泄漏哪?

java 中的堆棧是如何工做的哪

棧:當每次有新的方法運行時,就會在棧中加一個frame,也就是一個內存單元,保存該方法調用的參數,局部變量以及返回地址,而在方法結束後,對應的frame會被從棧中移除,局部變量佔用的空間也會被釋放。也就是說棧會本身對內存進行清理和釋放。

堆:java中new的對象都會存儲在堆中,當這些對象沒有再被引用時,就會等待被GC回收。若是咱們建立了大量的對象,而又一直被引用,就會致使這些對象一直沒法釋放,從而形成內存泄漏。java中的引用又分爲強,軟,弱,虛四種引用。而真正形成內存泄漏的實際上是強引用,由於GC不會回收一個強引用的對象。

 

4. Android中可能形成內存泄漏的情景,也就是強引用持有的狀況

(1) 全局進程的static變量

(2) Activity以外的一些線程,沒有清空對Activity的強引用

 

5. Android中可能致使內存泄漏的具體狀況

(1) static activity:在類中定義了靜態的activity變量,而在activity生命週期結束後又沒有清空

(2) static views:相似於上述的狀況

(3) Inner Classes:內部類雖然能夠提升代碼的可讀性以及封裝性,可是若是一個內部類持有了靜態變量的引用,並且忘記了銷燬的時候變爲null,就會致使內存泄漏

(4) Anonymous Classes:相似與Inner Classes

(5) handler:在沒有執行完handler message時,activity被銷燬了。或者handler使用完後並無釋放掉對象

(6) Threads

(7) TimerTask

(8) Sensor Manager

(9) SQL:數據庫查詢時忘了關閉掉遊標Cursor,雖然可能每次查詢數據量都不是很大,可是長時間的大量操做的狀況下是可能出現內存泄漏的

(10) Bitmap:程序中可能使用了太多本身建立的Bitmap,而忘記釋放掉,最多見的是Gallery以及ListView這種列表

 

6. Android中具體的內存泄漏分析和定位

檢測內存泄漏有一些經常使用的工具,好比MAT工具,AndroidStudio中自帶的分析工具,以及leakCanary,這些工具的使用後期打算專門寫文章介紹。

在Acitivity的生命週期中,在某些方法例如onPause(), onStop(), onDestory()方法中儘可能地釋放一些資源

儘可能使用getApplicationContext(),而避免使用create(this)

相關文章
相關標籤/搜索