1. 程式人生 > >Android和Java的垃圾回收

Android和Java的垃圾回收

來討論一下Android的GC操作,GC全稱是Garbage Collection,也就是所謂的垃圾回收。Android系統會在適當的時機觸發GC操作,一旦進行GC操作,就會將一些不再使用的物件進行回收。那麼哪些物件會被認為是不再使用,並且可以被回收的呢?我們來看下面一張圖:


上圖當中,每個藍色的圓圈就代表一個記憶體當中的物件,而圓圈之間的箭頭就是它們的引用關係。這些物件有些是處於活動狀態的,而有些就已經不再被使用了。那麼GC操作會從一個叫作Roots的物件開始檢查,所有它可以訪問到的物件就說明還在使用當中,應該進行保留,而其它的物件就表示已經不再被使用了,如下圖所示:


可以看到,目前所有黃色的物件仍然會被系統繼續保留,而藍色的物件就會在GC操作當中被系統回收掉了,這大概就是Android系統一次簡單的GC流程。

優先順序:前臺,可見,服務,後臺,empty

一般情況下一共有以下幾種觸發GC操作的原因:

  • GC_CONCURRENT:   當我們應用程式的堆記憶體快要滿的時候,系統會自動觸發GC操作來釋放記憶體。
  • GC_FOR_MALLOC:   當我們的應用程式需要分配更多記憶體,可是現有記憶體已經不足的時候,系統會進行GC操作來釋放記憶體。
  • GC_HPROF_DUMP_HEAP:   當生成HPROF檔案的時候,系統會進行GC操作,關於HPROF檔案我們下面會講到。
  • GC_EXPLICIT:   這種情況就是我們剛才提到過的,主動通知系統去進行GC操作,比如呼叫System.gc()方法來通知系統。或者在DDMS中,通過工具按鈕也是可以顯式地告訴系統進行GC操作的。(不要大量使用)

Java垃圾回收:

陣列和物件在沒有引用變數指向它的時候,才變成垃圾,不能再被使用,但是仍然佔著記憶體,在隨後的一個不確定的時間被垃圾回收器釋放掉。這個也是java比較佔記憶體的主要原因

當應用程式空閒時,即沒有應用執行緒在執行時,GC會被呼叫,Java垃圾回收執行緒就是一個典型的守護執行緒, 當我們的程式中不再有任何執行中的Thread,程式就不會再產生垃圾,垃圾回收器也就無事可做,所以當垃圾回收執行緒是Java虛擬機器上僅剩的執行緒時,Java虛擬機器會自動離開。 它始終在低級別的狀態中執行,用於實時監控和管理系統中的可回收資源。

只有程式需要更多額外記憶體或應用程式空閒時垃圾回收機制才會進行垃圾回收;只有一個物件處於不可達狀態,系統才會真正回收該物件所佔有的資源(堆記憶體和方法區)

程式無法精確控制垃圾回收的執行(但我們可以通知系統進行垃圾回收,System.gc(),但系統是否進行垃圾回收仍然不確定),只負責回收堆記憶體的物件,回收任何物件之前會呼叫它的finalize()方法

物件的三種狀態:

可達狀態:有一個以上的變數引用一個物件

可恢復狀態:不再有任何變數引用它,垃圾回收時系統會呼叫所有可恢復狀態的物件的finalize()方法進行資源清理,如果重新有引用變數引用該物件會變為可達狀態,否則進入不可達狀態

不可達狀態:沒有變數引用,且finalize()方法也沒使該物件變成可達狀態,永久失去引用

物件的四種引用:

強引用:建立一個物件,賦給一個引用變數,處於可達狀態,不可能被系統垃圾回收機制回收

軟引用:垃圾回收機制執行時,系統記憶體空間足夠不會被回收,不足夠會被回收

弱引用:垃圾回收機制執行時,不管系統記憶體是否足夠,都會被回收

虛引用:幾乎等於沒有引用,主要用於跟蹤物件被垃圾回收的狀態

gcRoots:

1、(棧幀中的本地變量表)中引用的物件

2、方法區中的靜態成員。

3、方法區中的常量引用的物件(全域性變數)

4、本地方法棧中JNI(一般說的Native方法)引用的物件。

 減少GC開銷的措施

  根據上述GC的機制,程式的執行會直接影響系統環境的變化,從而影響GC的觸發。若不針對GC的特點進行設計和編碼,就會出現記憶體駐留等一系列負面影響。為了避免這些影響,基本的原則就是儘可能地減少垃圾和減少GC過程中的開銷。具體措施包括以下幾個方面:

  (1)不要顯式呼叫System.gc()

  此函式建議JVM進行主GC,雖然只是建議而非一定,但很多情況下它會觸發主GC,從而增加主GC的頻率,也即增加了間歇性停頓的次數。

  (2)儘量減少臨時物件的使用

  臨時物件在跳出函式呼叫後,會成為垃圾,少用臨時變數就相當於減少了垃圾的產生,從而延長了出現上述第二個觸發條件出現的時間,減少了主GC的機會。

  (3)物件不用時最好顯式置為Null

  一般而言,為Null的物件都會被作為垃圾處理,所以將不用的物件顯式地設為Null,有利於GC收集器判定垃圾,從而提高了GC的效率。

  (4)儘量使用StringBuffer,而不用String來累加字串

  由於String是固定長的字串物件,累加String物件時,並非在一個String物件中擴增,而是重新建立新的String物件,如Str5=Str1+Str2+Str3+Str4,這條語句執行過程中會產生多個垃圾物件,因為對次作“+”操作時都必須建立新的String物件,但這些過渡物件對系統來說是沒有實際意義的,只會增加更多的垃圾。避免這種情況可以改用StringBuffer來累加字串,因StringBuffer是可變長的,它在原有基礎上進行擴增,不會產生中間物件。

  (5)能用基本型別如Int,Long,就不用Integer,Long物件

  基本型別變數佔用的記憶體資源比相應物件佔用的少得多,如果沒有必要,最好使用基本變數。

  (6)儘量少用靜態物件變數

  靜態變數屬於全域性變數,不會被GC回收,它們會一直佔用記憶體。

  (7)分散物件建立或刪除的時間

  集中在短時間內大量建立新物件,特別是大物件,會導致突然需要大量記憶體,JVM在面臨這種情況時,只能進行主GC,以回收記憶體或整合記憶體碎片,從而增加主GC的頻率。集中刪除物件,道理也是一樣的。它使得突然出現了大量的垃圾物件,空閒空間必然減少,從而大大增加了下一次建立新物件時強制主GC的機會。

相關推薦

AndroidJava垃圾回收

來討論一下Android的GC操作,GC全稱是Garbage Collection,也就是所謂的垃圾回收。Android系統會在適當的時機觸發GC操作,一旦進行GC操作,就會將一些不再使用的物件進行回

java垃圾回收機制調優

user 機制 xmx erp 存儲 這樣的 其他應用 pan time                           java垃圾回收機制和調優 gc即垃圾收集機制是指jvm用於釋放那些不再使用的對象所占用的內存。java語言並不要求jvm有gc,也沒有規定gc如何

Java垃圾回收——優點原理

優點:a.不需要考慮記憶體管理, b.可以有效的防止記憶體洩漏,有效的利用可使用的記憶體, c.由於有垃圾回收機制,Java中的物件不再有"作用域"的概念,只有物件的引用才有"作用域" 原理:垃圾回收器是作為一個單獨的低級別的執行緒執行,在不可知的情況下對記憶體堆中已死

java垃圾回收之Minor GCMajor GC

最近在讀周志明寫的 深入理解Java虛擬機器:JVM高階特性與最佳實踐 對Minor GC和Major GC做點筆記  新生代 GC(Minor GC):指發生在新生代的垃圾收集動作,因為 Java 物件大多都具 備朝生夕滅的特性,所以 Minor GC 非常頻繁

Java 垃圾回收(GC) 泛讀

其中 中斷 bsp 之前 後臺 轉換 actions 一次 需要 Java 垃圾回收(GC) 泛讀 文章地址:https://segmentfault.com/a/1190000008922319 0. 序言 帶著問題去看待 垃圾回收(GC) 會比較好,一般來說主要的疑

Java垃圾回收算法

分代 清理 java 利用 效果 大小 ava 大量 思想 1.標記-清除算法 概念 標記階段:先通過根節點,標記所有從根節點開始的可達對象,因此,未被標記的對象就是未被引用的垃圾對象; 清除階段:清除所有未被標記的對象。 缺點: 標記和清除的過程效率不高(標記和清除都需要

Java垃圾回收(GC)機制詳解

nbsp 引用計數 維護 png 對象 最新 新的 com 前沿 垃圾回收算法有兩種,根據不同的虛擬機策略不同 1、引用計數法 2、可達性分析法 由於我們平常使用的hotspot虛擬機用的是第二種。 那哪些是可達的呢? 這個算法的基本思想是通過一系列稱為“GC Roots”

JavaGC專家(1)—深入淺出Java垃圾回收機制

java性能優化 追蹤 jdk5 structure 每一個 內存管理 過程 hot ati 在學習GC之前,你首先應該記住一個單詞:“stop-the-world”。Stop-the-world會在任何一種GC算法中發生。Stop-the-world意味著 JVM 因為要

aNDROIDJaVa的小夥伴

小夥伴 ongl com hao123 .com java http baidu oid aNDROID%E8%B0%83%E8%AF%95%E6%97%B6%E7%9A%84%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98 http://music

深入理解 Java 垃圾回收機制

nbsp 循環引用 方式 不同的 整理 一個 復制 垃圾回收機制 提高 垃圾回收機制中的算法: 1.引用計數法:無法檢測出循環引用。如父對象有一個對子對象的引用,子對象反過來引用父對象。這樣,他們的引用計數永遠不可能為0. 2 標記-清除算法:采用從根集合進行掃描,對存活

轉:深入淺出Java垃圾回收機制

但是 enter 相關 html 帶來 生命周期 不同 追蹤 lee 原文鏈接:http://www.importnew.com/1993.html 對於Java開發人員來說,了解垃圾回收機制(GC)有哪些好處呢?首先可以滿足作為一名軟件工程師的求知欲,其次,深入了解GC如

細述 Java垃圾回收機制→Types of Java Garbage Collectors

ade con -s 通過 分享 釋放 數組 collect 程序員 細述 Java垃圾回收機制→Types of Java Garbage Collectors 轉自:https://segmentfault.com/a/1190000006214497

java垃圾回收機制的使用

checkout ati pub bool logs int [] ring static public class Test { public static void main(String[] args) throws Exception {

Java 垃圾回收機制(早期版本)

重新 速度 交互 綜合 技術 -1 遍歷 我們 後臺 Java 垃圾回收機制在我們普通理解來看,應該視為一種低優先級的後臺進程來實現的,其實早期版本的Java虛擬機並非以這種方式實現的。 先從一種很簡單的垃圾回收方式開始。 引用計數   引用計數是一種簡單但是速度很慢

Java垃圾回收原理(2)

垃圾回收 Java虛擬機采用一種自適應的垃圾回收技術。依據的思想:對任何“活”的對象,一定能最終追溯到其存活在堆棧或靜態存儲區之中的引用。這個引用鏈條可能會穿過數個對象層次。由此,如果從堆棧和靜態存儲區開始,遍歷所有的引用,就能找到所有活的對象。對於發現的每個引用,必須追蹤它所引用的對象,然後是此對象所

深入解析Java垃圾回收機制

normal tor 技術分享 統計分析 time method 堆內存 出棧 類結構 引入垃圾回收 哪些內存需要回收? 引用計數法 可達性分析 如何回收 Marking 標記 Normal Deletion 清除 Deletion with Compacting 壓縮

深入理解java垃圾回收算法

信息 pan 一半 rms err 必須 輪換 找到 兩個 Java虛擬機的內存區域中,程序計數器、虛擬機棧和本地方法棧三個區域是線程私有的,隨線程生而生,隨線程滅而滅;棧中的棧幀隨著方法的進入和退出而進行入棧和出棧操作,每個棧幀中分配多少內存基本上是在類結構確定下來時就已

Java 垃圾回收機制

導致 垃圾回收 事件 相互 等於 理論 不同 基礎 其中 1.如何確定對象是個垃圾?   引用計數法:實現簡單、效率高,但是如何兩個對象同時等於null,他們會相互引用,導致他們的引用計數都不為0,永遠不會被回收。   可達性分析法: 2.典型的垃圾收集算法   標記-清楚

成為JavaGC專家(3)—如何監控Java垃圾回收機制(轉載)

生成 head builder 清除 內存清理 每次 com con book 原文:http://www.importnew.com/3146.html 為什麽需要優化GC 或者說的更確切一些,對於基於Java的服務,是否有必要優化GC?應該說,對於所有的基於Java的服

Java垃圾回收概覽

引用計數 AR ner 一次 一半 vivo HA finalize 這一 GC要解決三個主要的問題: 哪些內存需要回收? 什麽時候回收? 如何回收? 哪些內存需要回收? 最簡單的是引用計數(reference count),缺陷是無法解決循環引用。於是更快點的