Android 性能優(yōu)化之GC學習篇

內(nèi)存優(yōu)化篇

  • memory贡耽、GC冗恨、Performance
    GC(Garbage Collection):垃圾回收是jvm提供的一種垃圾回收機制增显,回收的是無任何對象引用指向的內(nèi)存空間时鸵。垃圾回收釋放的是對象占據(jù)的內(nèi)存(一般為堆內(nèi)存)斋日;一般在程序空閑時間不定時回收。
java中的對象引用:
  • 強引用(Strong Reference):如Object obj = new Object()挠羔,只要對象還存在井仰,對象引用的地址就永遠不會被回收。

  • 軟引用(Soft Reference):定義的對象為非必需的破加。在系統(tǒng)內(nèi)存不夠用時俱恶,軟引用關(guān)聯(lián)的對象被垃圾收集器回收。JDK1.2之后提供SoftReference類來實現(xiàn)軟引用范舀。

  • 弱引用(Weak Reference):定義的對象是非必需的合是,強度比軟引用弱,弱引用關(guān)聯(lián)的對象只能生存到下一次垃圾收集發(fā)生之前锭环。當垃圾收集器工作時聪全,無論當前內(nèi)存是否足夠,都會回收弱引用對象引用的內(nèi)存辅辩。在JDK1.2之后难礼,提供WeakReference類來實現(xiàn)弱引用。

  • 虛引用(Phantom Reference):最弱的一種引用關(guān)系玫锋,完全不會對其生存時間構(gòu)成影響蛾茉,也無法通過虛引用來取得一個對象實例。為一個對象設(shè)置虛引用關(guān)聯(lián)的唯一目的是希望能在這個對象被收集器回收時收到一個系統(tǒng)通知撩鹿。JDK1.2之后提供PhantomReference類來實現(xiàn)虛引用谦炬。

  • 檢索回收的對象
    jvm會查詢所有未銷毀的對象->回收垃圾對象占用的內(nèi)存。

  • 垃圾對象的確認(引用計數(shù))
    其實不管是Object-C還是java,都是通過一個引用計數(shù)的原理來跟蹤一個對象的使用情況键思,每個對象從被創(chuàng)建那一時刻起就會有一個引用計數(shù)器伴其一生础爬。

  • 對象被初始化時計數(shù)器值為1 -> 被另一個對象引用時加1 -> 引用的對象為null時,減1 -> 計數(shù)為0時jvm視其為垃圾吼鳞。
  • 優(yōu)點:引用計數(shù)收集器執(zhí)行簡單看蚜,判定效率高,交織在程序運行中赖条。對程序不被長時間打斷的實時環(huán)境比較有利(OC的內(nèi)存管理使用該算法)失乾。

  • 缺點: 難以檢測出對象之間的循環(huán)引用常熙。同時纬乍,引用計數(shù)器增加了程序執(zhí)行的開銷。所以Java語言并沒有選擇這種算法進行垃圾回收裸卫。

  • 早期的JVM使用引用計數(shù)仿贬,現(xiàn)在大多數(shù)JVM采用對象引用遍歷(根搜索算法)。

  • Java的堆內(nèi)存(Java Heap Memory)

Java的堆內(nèi)存基于Generation算法(Generational Collector)劃分為新生代墓贿、年老代和持久代茧泪。新生代又被進一步劃分為Eden和Survivor區(qū),最后Survivor由FromSpace(Survivor0)和ToSpace(Survivor1)組成聋袋。所有通過new創(chuàng)建的對象的內(nèi)存都在堆中分配队伟,其大小可以通過-Xmx和-Xms來控制。

  • 堆內(nèi)存分配區(qū)域:

1.年輕代(Young Generation)

幾乎所有新生成的對象首先都是放在年輕代的幽勒。新生代內(nèi)存按照8:1:1的比例分為一個Eden區(qū)和兩個Survivor(Survivor0,Survivor1)區(qū)嗜侮。大部分對象在Eden區(qū)中生成。當新對象生成啥容,Eden Space申請失斝饪拧(因為空間不足等),則會發(fā)起一次GC(Scavenge GC)咪惠』髦ǎ回收時先將Eden區(qū)存活對象復制到一個Survivor0區(qū),然后清空Eden區(qū)遥昧,當這個Survivor0區(qū)也存放滿了時覆醇,則將Eden區(qū)和Survivor0區(qū)存活對象復制到另一個Survivor1區(qū),然后清空Eden和這個Survivor0區(qū)炭臭,此時Survivor0區(qū)是空的叫乌,然后將Survivor0區(qū)和Survivor1區(qū)交換,即保持Survivor1區(qū)為空徽缚, 如此往復憨奸。當Survivor1區(qū)不足以存放 Eden和Survivor0的存活對象時,就將存活對象直接存放到老年代凿试。當對象在Survivor區(qū)躲過一次GC的話排宰,其對象年齡便會加1似芝,默認情況下,如果對象年齡達到15歲板甘,就會移動到老年代中党瓮。若是老年代也滿了就會觸發(fā)一次Full GC,也就是新生代盐类、老年代都進行回收寞奸。新生代大小可以由-Xmn來控制,也可以用-XX:SurvivorRatio來控制Eden和Survivor的比例在跳。

2.年老代(Old Generation)

在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對象枪萄,就會被放到年老代中。因此猫妙,可以認為年老代中存放的都是一些生命周期較長的對象瓷翻。內(nèi)存比新生代也大很多(大概比例是1:2),當老年代內(nèi)存滿時觸發(fā)Major GC即Full GC割坠,F(xiàn)ull GC發(fā)生頻率比較低齐帚,老年代對象存活時間比較長,存活率標記高彼哼。一般來說对妄,大對象會被直接分配到老年代。所謂的大對象是指需要大量連續(xù)存儲空間的對象敢朱,最常見的一種大對象就是大數(shù)組剪菱。比如:
byte[] data = new byte[410241024]
這種一般會直接在老年代分配存儲空間。
當然分配的規(guī)則并不是百分之百固定的蔫饰,這要取決于當前使用的是哪種垃圾收集器組合和JVM的相關(guān)參數(shù)琅豆。

3.持久代(Permanent Generation)

用于存放靜態(tài)文件(class類、方法)和常量等篓吁。持久代對垃圾回收沒有顯著影響茫因,但是有些應(yīng)用可能動態(tài)生成或者調(diào)用一些class,例如Hibernate 等杖剪,在這種時候需要設(shè)置一個比較大的持久代空間來存放這些運行過程中新增的類冻押。對永久代的回收主要回收兩部分內(nèi)容:廢棄常量和無用的類。
永久代空間在Java SE8特性中已經(jīng)被移除盛嘿。取而代之的是元空間(MetaSpace)洛巢。因此不會再出現(xiàn)“java.lang.OutOfMemoryError: PermGen error”錯誤。

  • 堆內(nèi)存分配策略明確以下三點:

(1)對象優(yōu)先在Eden分配次兆。

(2)大對象直接進入老年代稿茉。

(3)長期存活的對象將進入老年代。

  • 對垃圾回收機制說明以下三點:

新生代GC(Minor GC/Scavenge GC):發(fā)生在新生代的垃圾收集動作。因為Java對象大多都具有朝生夕滅的特性漓库,因此Minor GC非常頻繁(不一定等Eden區(qū)滿了才觸發(fā))恃慧,一般回收速度也比較快。在新生代中渺蒿,每次垃圾收集時都會發(fā)現(xiàn)有大量對象死去痢士,只有少量存活,因此可選用復制算法來完成收集茂装。
老年代GC(Major GC/Full GC):發(fā)生在老年代的垃圾回收動作怠蹂。Major GC,經(jīng)常會伴隨至少一次Minor GC少态。由于老年代中的對象生命周期比較長城侧,因此Major GC并不頻繁,一般都是等待老年代滿了后才進行Full GC况增,而且其速度一般會比Minor GC慢10倍以上赞庶。另外训挡,如果分配了Direct Memory澳骤,在老年代中進行Full GC時,會順便清理掉Direct Memory中的廢棄對象澜薄。而老年代中因為對象存活率高为肮、沒有額外空間對它進行分配擔保,就必須使用標記—清除算法或標記—整理算法來進行回收肤京。
新生代采用空閑指針的方式來控制GC觸發(fā)颊艳,指針保持最后一個分配的對象在新生代區(qū)間的位置,當有新的對象要分配內(nèi)存時忘分,用于檢查空間是否足夠棋枕,不夠就觸發(fā)GC。當連續(xù)分配對象時妒峦,對象會逐漸從Eden到Survivor重斑,最后到老年代。
用Java VisualVM來查看肯骇,能明顯觀察到新生代滿了后窥浪,會把對象轉(zhuǎn)移到舊生代,然后清空繼續(xù)裝載笛丙,當老年代也滿了后漾脂,就會報outofmemory的異常,

參考 http://www.reibang.com/p/5261a62e4d29

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胚鸯,一起剝皮案震驚了整個濱河市骨稿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖坦冠,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件镜豹,死亡現(xiàn)場離奇詭異,居然都是意外死亡蓝牲,警方通過查閱死者的電腦和手機趟脂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來例衍,“玉大人昔期,你說我怎么就攤上這事》鹦” “怎么了硼一?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長梦抢。 經(jīng)常有香客問我般贼,道長,這世上最難降的妖魔是什么奥吩? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任哼蛆,我火速辦了婚禮,結(jié)果婚禮上霞赫,老公的妹妹穿的比我還像新娘腮介。我一直安慰自己,他們只是感情好端衰,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布叠洗。 她就那樣靜靜地躺著,像睡著了一般旅东。 火紅的嫁衣襯著肌膚如雪灭抑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天抵代,我揣著相機與錄音腾节,去河邊找鬼。 笑死主守,一個胖子當著我的面吹牛禀倔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播参淫,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼救湖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了涎才?” 一聲冷哼從身側(cè)響起鞋既,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤力九,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后邑闺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跌前,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年陡舅,在試婚紗的時候發(fā)現(xiàn)自己被綠了抵乓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡靶衍,死狀恐怖灾炭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情颅眶,我是刑警寧澤蜈出,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站涛酗,受9級特大地震影響铡原,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜商叹,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一燕刻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沈自,春花似錦酌儒、人聲如沸辜妓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽籍滴。三九已至酪夷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孽惰,已是汗流浹背晚岭。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勋功,地道東北人坦报。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像狂鞋,于是被迫代替她去往敵國和親片择。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1.什么是垃圾回收骚揍? 垃圾回收(Garbage Collection)是Java虛擬機(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,547評論 17 311
  • JVM架構(gòu) 當一個程序啟動之前字管,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū))啰挪,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,673評論 0 7
  • 原文閱讀 前言 這段時間懈怠了,罪過嘲叔! 最近看到有同事也開始用上了微信公眾號寫博客了亡呵,挺好的~給他們點贊,這博客我...
    碼農(nóng)戲碼閱讀 5,987評論 2 31
  • 一 硫戈、java虛擬機底層結(jié)構(gòu)詳解 我們知道锰什,一個JVM實例的行為不光是它自己的事,還涉及到它的子系統(tǒng)丁逝、存儲區(qū)域歇由、...
    葡萄喃喃囈語閱讀 1,488評論 0 4
  • 作者:一字馬胡 轉(zhuǎn)載標志 【2017-11-12】 更新日志 日期更新內(nèi)容備注 2017-11-12新建文章初版 ...
    beneke閱讀 2,210評論 0 7