成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Jvm系列:從一個(gè)題目簡析GC垃圾回收

Neilyo / 2264人閱讀

摘要:第二步分析第一個(gè)循環(huán)即表示產(chǎn)生的對象,后面規(guī)律相同和會(huì)直接放入?yún)^(qū)。因?yàn)閮?yōu)先放區(qū),而且夠放,此時(shí)為兩者表示已用剩余。此值一般設(shè)置與相同以避免每次垃圾回收完后重新分配內(nèi)存設(shè)置年輕代大小為。

一、概述

閑來有空翻翻書,撿撿一些基礎(chǔ)點(diǎn),就當(dāng)靜下心多寫字。
Java基礎(chǔ)的東西無論怎么樣都會(huì)想到JVM,而提JVM必然想到最常見的一些點(diǎn):字節(jié)碼加載,類初始化,方法執(zhí)行,對象內(nèi)存分配和回收,線程和鎖機(jī)制等等。歸納整理的時(shí)候,怎么可以少了它們。不過,我打算換個(gè)方式,不寫太多概念(網(wǎng)上一搜一把的),想從一些代碼、例子、題目或者疑問等方面來寫寫。

二、背景知識

JVM內(nèi)存管理需要理解的點(diǎn):內(nèi)存空間的劃分、內(nèi)存分配和內(nèi)存回收。

內(nèi)存空間:認(rèn)識方法區(qū)、堆區(qū)、本地方法棧等幾個(gè)空間,了解堆的分代管理。

內(nèi)存分配:在Java中這塊比較容易,就是棧和堆,而創(chuàng)建對象都在堆區(qū)。

內(nèi)存回收:實(shí)戰(zhàn)上最主要是關(guān)注什么時(shí)候會(huì)觸發(fā)回收(GC)和回收對性能的影響,學(xué)習(xí)上可以了解不同回收起和回收算法。

驗(yàn)證和測試需要的點(diǎn):常見的啟動(dòng)參數(shù)、GUI類工具。

常見的啟動(dòng)參數(shù):-Xms -Xmx -Xmn 等等

GUI類工具:JProfiler(推薦)、JVisualVM、MAT、JMap、JHat。

三、一個(gè)GC題目

1)當(dāng)用-Xms30m -Xmx30m -Xmn10m -XX:+UseParallelGC 執(zhí)行上面的代碼時(shí)會(huì)執(zhí)行幾次Minor GC和幾次Full GC呢?
2)分別說明你的結(jié)果是如何推出來的?

public static void main(String[] args) throws Exception{
    List caches=new ArrayList();
    for(int i=0;i<7;i++){
        caches.add(new byte[10241024*3]);
    }
    caches.clear();
    for(int j=0;j<2;j++){
        caches.add(new byte[10241024*3]);
    }
    Thread.sleep(5000);
}

先思考下,別忙著往下看,萬一我的分析并不對呢?。?/strong>
先思考下,別忙著往下看,萬一我的分析并不對呢??!
先思考下,別忙著往下看,萬一我的分析并不對呢??!

四、小白式的分析過程

第一步分析啟動(dòng)參數(shù):
首先,看到"UseParallelGC"參數(shù),表示這里采用的是“Parallel Scavenge+Serial Old”。那么,從回收器的類型,可以知道堆的新生代是基于復(fù)制算法的gc(即內(nèi)存模型有from和to區(qū)),堆的老年代則基于標(biāo)記-整理算法。
其次,看到"-Xms30m -Xmx30m"參數(shù),表示堆區(qū)最大為30M,且不會(huì)動(dòng)態(tài)擴(kuò)展。
最后,再看到"-Xmn10m"參數(shù),表示新生代區(qū)為10m,而且采用默認(rèn)的7.5:1,即Eden7.5M(7680k),而from和to區(qū)各為1.25M。

第二步分析第一個(gè)循環(huán)
i0(即表示i=0產(chǎn)生的對象,后面規(guī)律相同)和i1 會(huì)直接放入Eden區(qū)。因?yàn)閮?yōu)先放Eden區(qū),而且夠放,此時(shí)Eden為 6m/7.5m.(兩者表示 已用/剩余 。此處的6m為近似值,其他jvm對象之類占用內(nèi)存的,不細(xì)討論)。

i2來了,要放入Eden區(qū),發(fā)現(xiàn)空間不夠。觸發(fā)MinorGC。然后把i2放到Eden。
結(jié)果將i0~i1直接誒轉(zhuǎn)入老年代 ,原因是對象3m太大放不了From區(qū)(前面提到才1.25m)。
此時(shí)Eden區(qū) 3m/7.5m 老年代6m/20m
gc的log --> [PSYoungGen: 6451K->272K(8960K)] 6451K->6416K(29440K)

i3來了,直接繼續(xù)放入Eden區(qū)。 此時(shí)Eden區(qū) 6m/7.5m 老年代6m/20m

i4來了,跟i2一樣的情況,發(fā)現(xiàn)Eden不夠放了。再次觸發(fā)MinorGC。然后把i4放到Eden。
結(jié)果將i2~i3直接誒轉(zhuǎn)入老年代,去陪i0和i1了。
此時(shí)Eden區(qū) 3m/7.5m 老年代12m/20m
gc的log --> [PSYoungGen: 6650K->256K(8960K)] 12794K->12544K(29440K)

i5來了,繼續(xù)放入Eden區(qū),此時(shí)加上前面i4,Eden區(qū) 6m/7.5m 老年代12m/20m

i6來了,跟前面i2、i4情況一樣,觸發(fā)了一次MinorGC。然后把i6放到Eden。
結(jié)果: i6 在Eden,i0~i5 6個(gè)在老年代。 此時(shí)Eden區(qū) 3m/7.5m 老年代18m/20m
gc的log -->[PSYoungGen: 6453K->224K(8960K)] 18741K->18656K(29440K)
這里還多了一次FullGC。
gc的log -->[PSYoungGen: 240K->0K(8960K)] [PSOldGen: 18432K->18593K(20480K)]
暫時(shí)未能完全分析明白這點(diǎn),但gc日志來猜測,應(yīng)該是標(biāo)記-整理起作用了,為了整理出連續(xù)的空間吧。

第三步: 由于執(zhí)行了caches.clear(); 等于宣告前面的i0~i6的7個(gè)對象都不可用了(即GC Roots不可達(dá))
但還由于各區(qū)都有足夠大的空間,只要程序運(yùn)行未達(dá)到"GC安全點(diǎn)"是不會(huì)觸發(fā)GC的。

第四步:
j0來了,它會(huì)繼續(xù)放到Eden區(qū),此時(shí)陪著還沒回收的i6。
此時(shí)Eden區(qū) 6m/7.5m 老年代18m/20m

j1來了,這時(shí)候內(nèi)存管理會(huì)發(fā)現(xiàn)新生代和老年代都不夠空間申請了,即觸發(fā)FullGC。
結(jié)果:從老年代把不可用的i0~i5全部干掉,再把j0移入老年代,再把新生代中的i6干掉,然后j1放入新生代。
此時(shí)Eden區(qū) 3m/7.5m 老年代3m/20m
gc的log -->[PSYoungGen: 6178K->0K(8960K)] [PSOldGen: 18593K->3233K(20480K)]

五、通過運(yùn)行程序,驗(yàn)證分析

運(yùn)行上面的程序,參數(shù)為: -Xms30m -Xmx30m -Xmn10m -XX:+UseParallelGC -XX:+PrintGCDetails
加上-XX:+PrintGCDetails,這樣可以打印GC的log情況來驗(yàn)證前面的分析。

ps:不同的虛擬機(jī)版本打印的輸出多少會(huì)有差異,以下log,是我在sum的1.6.0_43版本打印出來的,另外刪減掉一些不關(guān)心的輸出。

[GC [PSYoungGen: 6451K->320K(8960K)]
[GC [PSYoungGen: 6698K->240K(8960K)]
[GC [PSYoungGen: 6437K->240K(8960K)]
[Full GC [PSYoungGen: 240K->0K(8960K)] [PSOldGen: 18432K->18594K(20480K)] 18672K->18594K(29440K)
[Full GC [PSYoungGen: 6178K->0K(8960K)] [PSOldGen: 18594K->3234K(20480K)] 24773K->3234K(29440K)
Heap
PSYoungGen total 8960K, used 3248K
    >eden space 7680K, 42% used
    >from space 1280K, 0% used
    >to space 1280K, 0% used
PSOldGen total 20480K, used 3234K
PSPermGen total 21248K, used 3043K
六、最后補(bǔ)充涉及到的知識點(diǎn) 6.1 關(guān)于堆區(qū)分代管理

新生代GC(Minor GC):主要是發(fā)生在新生代的收集動(dòng)作,據(jù)說IBM做過調(diào)查,絕大多數(shù)對象都是朝生夕死,所以MinorGC非常頻繁,速度也比較快。
老年代GC(Full GC):是指發(fā)生在老年代的收集動(dòng)作,但是通常也會(huì)對年輕代進(jìn)行垃圾收集。

6.2 GC幾個(gè)參數(shù)說明

-Xmx 設(shè)置JVM最大可用內(nèi)存為30M。
-Xms 設(shè)置JVM擴(kuò)展內(nèi)存為30M。(此值一般設(shè)置與-Xmx相同,以避免每次垃圾回收完后JVM重新分配內(nèi)存)
-Xmn:設(shè)置年輕代大小為10m。 (整個(gè)堆大小=年輕代大小 + 年老代大小 持久代大小 : 持久代PermGen是非堆的,可以通過jconsole查看)
-Xss128k:(設(shè)置每個(gè)線程的堆棧大小)
持久代,是通過PermSize和MaxPermSize
-XX:+UseParallelGC:選擇垃圾收集器為并行收集器。

6.3 不同類型處理器

串行處理器: 適用數(shù)據(jù)量比較?。?00M左右);單處理器下并且對響應(yīng)時(shí)間無要求的應(yīng)用。 缺點(diǎn):只能用于小型應(yīng)用
并行處理器: 適用“對吞吐量有高要求”,多CPU、對應(yīng)用響應(yīng)時(shí)間無要求的中、大型應(yīng)用。舉例:后臺處理、科學(xué)計(jì)算。 缺點(diǎn):應(yīng)用響應(yīng)時(shí)間可能較長
并發(fā)處理器: 適用“對響應(yīng)時(shí)間有高要求”,多CPU、對應(yīng)用響應(yīng)時(shí)間有較高要求的中、大型應(yīng)用。舉例:Web服務(wù)器/應(yīng)用服務(wù)器、電信交換、集成開發(fā)環(huán)境。

6.4 其它

GC Roots不可達(dá):GC回收過程判斷對象是否可以回收的一種方式,叫可達(dá)性測試!
打印gc日志:啟動(dòng)程序時(shí)加vm參數(shù)-XX:+PrintGCDetails。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65587.html

相關(guān)文章

  • 學(xué)習(xí)JVM是如何入門到放棄的?

    摘要:而字節(jié)碼運(yùn)行在之上,所以不用關(guān)心字節(jié)碼是在哪個(gè)操作系統(tǒng)編譯的,只要符合規(guī)范,那么,這個(gè)字節(jié)碼文件就是可運(yùn)行的。好處防止內(nèi)存中出現(xiàn)多份同樣的字節(jié)碼安全性角度特別說明類加載器在成功加載某個(gè)類之后,會(huì)把得到的類的實(shí)例緩存起來。 前言 只有光頭才能變強(qiáng) JVM在準(zhǔn)備面試的時(shí)候就有看了,一直沒時(shí)間寫筆記?,F(xiàn)在到了一家公司實(shí)習(xí),閑的時(shí)候就寫寫,刷刷JVM博客,刷刷電子書。 學(xué)習(xí)JVM的目的也很簡單...

    Joyven 評論0 收藏0
  • Java 垃圾回收(GC) 泛讀

    摘要:在這種消耗很高的狀態(tài)下,應(yīng)用程序所有的線程都會(huì)掛起,暫停一切正常的工作,等待垃圾回收的完成。但是,因?yàn)榫€程切換和上下文轉(zhuǎn)換的消耗,會(huì)使得垃圾回收的總體成本上升,造成系統(tǒng)吞吐量的下降。 Java 垃圾回收(GC) 泛讀 文章地址: https://segmentfault.com/a/1190000008922319 0. 序言 帶著問題去看待 垃圾回收(GC) 會(huì)比較好,一般來說主要的...

    haoguo 評論0 收藏0
  • 細(xì)述 Java垃圾回收機(jī)制→How Java Garbage Collection Works?

    摘要:當(dāng)一個(gè)實(shí)例被創(chuàng)建的時(shí)候,它最初被存放在堆內(nèi)存空間的年輕代的區(qū)中。老年代或者永久代是堆內(nèi)存的第二個(gè)邏輯部分。在垃圾回收過程中掃描屬于部分的堆內(nèi)存。一旦實(shí)例從堆內(nèi)存中刪除了,它們原來的位置將空出來給以后分配實(shí)例使用。 本文非原創(chuàng),翻譯自How Java Garbage Collection Works?在Java中為對象分配和釋放內(nèi)存空間都是由垃圾回收線程自動(dòng)執(zhí)行完成的。和C語言不一樣的是...

    cc17 評論0 收藏0
  • java jvm

    摘要:本人使用的是,以下涉及的默認(rèn)值均以該版本為準(zhǔn)。其中,新生代被細(xì)分為和兩個(gè)區(qū)域,這兩個(gè)區(qū)域分別被命名為和,以示區(qū)分。其中新生帶存放新生的對象或者年齡不大的對象,老年代則存放老年對象。 什么是垃圾回收機(jī)制 不定時(shí)去堆內(nèi)存中清理不可達(dá)對象。不可達(dá)的對象并不會(huì)馬上就會(huì)直接回收, 垃圾收集器在一個(gè)Java程序中的執(zhí)行是自動(dòng)的,不能強(qiáng)制執(zhí)行,即使程序員能明確地判斷出有一塊內(nèi)存已經(jīng)無用了,是應(yīng)該回收...

    Lsnsh 評論0 收藏0
  • 談一談JVM垃圾回收

    摘要:這個(gè)算法看似不錯(cuò)而且簡單,不過存在這一個(gè)致命傷當(dāng)兩個(gè)對象互相引用的時(shí)候,就永遠(yuǎn)不會(huì)被回收于是引用計(jì)數(shù)算法就永遠(yuǎn)回收不了這兩個(gè)對象,下面介紹另一種算法。 前言 ? 如果要問Java與其他編程語言最大的不同是什么,我第一個(gè)想到的一定就是Java所運(yùn)行的JVM所自帶的自動(dòng)垃圾回收機(jī)制,以下是我學(xué)習(xí)JVM垃圾回收機(jī)制整理的筆記,希望能對讀者有一些幫助。 哪些內(nèi)存需要回收?what? ? ...

    stormzhang 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<