談談openjdk:
在正式往下學習JVM之前,這里談談openjdk這個網站,這個在學習java並發時也用過它來分析過鎖的底層實現,如:https://www.cnblogs.com/webor2006/p/11442551.html,為啥要說它,目前學習JVM已經記錄了80多篇了,從純小白到目前的學習貌似對JVM有東東了解得還不錯了,但是!!其實還只是了解了個冰山一角,主要是JVM是一個太龐大的知識領域了,畢境不是真正在商業公司里做過JVM相關的工作,所以對於它的新知識在未來會一直出現,那在面對網上新出的一些理論上的說明,怎么知道它是真的還是假的,或者說這些理論的來源是在哪里呢?如果有想法驗證的話就可以通過這個openjdk的底層JVM的源代碼來進行,所以這里打開openjdk再提一下:
然后隨便打開一個目錄則就可以看到大量的底層C++實現:
談這么一個小點就是假如未來想再進一步的探討JVM自己來求驗的話可以通過這種方式來進行,僅此而已。
G1回收器日志內容詳細分析:
在前面學習了大量的關於G1收集器相關的理論之后,下面則編寫一個實際的例子來看一下G1回收器產生日志跟之前咱們學習的其它的回收器產生的日志有啥區別,其實區別是非常之大的,如下:
就是在內存中申請了4M的大小,如果不加任何參數運行當然比較簡單:
好,接下來就是配置一下運行參數,我們目前用的JDK版本是1.8,默認它的收集器並非是G1收集器,而1.9之后則默認收集器就變為G1了,所以得顯示的指定一下,如下:
這三個參數之前都配過,這里再解釋一下:
-verbose:gc:此代表會輸出GC的詳細日志。
-Xms10m、-Xmx10m:堆內存指定10m,不可以擴容,為了更容易打出相關日志這里將堆內存指定小一點。
接着第三個參數,這個就比較重要了:
指定用G1垃圾收集器,接着再繼續添加其它參數:
接下來再來指定最大的停頓時間,這個在之前的理論中也已經提及過,回憶下:
配置一下:
好,此時再運行一下:
2019-11-12T11:39:25.103-0800: [GC pause (G1 Humongous Allocation) (young) (initial-mark), 0.0011864 secs] [Parallel Time: 0.8 ms, GC Workers: 4] [GC Worker Start (ms): Min: 226.6, Avg: 226.7, Max: 226.7, Diff: 0.1] [Ext Root Scanning (ms): Min: 0.3, Avg: 0.3, Max: 0.4, Diff: 0.1, Sum: 1.3] [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] [Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0] [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.1] [Object Copy (ms): Min: 0.3, Avg: 0.3, Max: 0.4, Diff: 0.0, Sum: 1.3] [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] [Termination Attempts: Min: 1, Avg: 1.5, Max: 3, Diff: 2, Sum: 6] [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1] [GC Worker Total (ms): Min: 0.6, Avg: 0.7, Max: 0.7, Diff: 0.1, Sum: 2.8] [GC Worker End (ms): Min: 227.4, Avg: 227.4, Max: 227.4, Diff: 0.0] [Code Root Fixup: 0.0 ms] [Code Root Purge: 0.0 ms] [Clear CT: 0.1 ms] [Other: 0.3 ms] [Choose CSet: 0.0 ms] [Ref Proc: 0.2 ms] [Ref Enq: 0.0 ms] [Redirty Cards: 0.1 ms] [Humongous Register: 0.0 ms] [Humongous Reclaim: 0.0 ms] [Free CSet: 0.0 ms] [Eden: 1024.0K(6144.0K)->0.0B(2048.0K) Survivors: 0.0B->1024.0K Heap: 2916.7K(10.0M)->2448.1K(10.0M)] [Times: user=0.00 sys=0.00, real=0.00 secs] 2019-11-12T11:39:25.104-0800: [GC concurrent-root-region-scan-start] 2019-11-12T11:39:25.105-0800: [GC concurrent-root-region-scan-end, 0.0005396 secs] 2019-11-12T11:39:25.105-0800: [GC concurrent-mark-start] 2019-11-12T11:39:25.105-0800: [GC concurrent-mark-end, 0.0000373 secs] 2019-11-12T11:39:25.106-0800: [GC remark 2019-11-12T11:39:25.106-0800: [Finalize Marking, 0.0068794 secs] 2019-11-12T11:39:25.113-0800: [GC ref-proc, 0.0000470 secs] 2019-11-12T11:39:25.113-0800: [Unloading, 0.0008433 secs], 0.0080039 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 2019-11-12T11:39:25.114-0800: [GC cleanup 3472K->3472K(10M), 0.0002695 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] hello world Heap garbage-first heap total 10240K, used 4496K [0x00000007bf600000, 0x00000007bf700050, 0x00000007c0000000) region size 1024K, 2 young (2048K), 1 survivors (1024K) Metaspace used 2656K, capacity 4486K, committed 4864K, reserved 1056768K class space used 287K, capacity 386K, committed 512K, reserved 1048576K Process finished with exit code 0
呃,看着頭暈。。輸出了這么多信息。。要想理解G1,分析日志是必須經歷過的,所以接下來硬着頭皮大致來分析一下:
啥意思?這個得回憶一下之前學的理論了,當時提到過這個“Humongous”,https://www.cnblogs.com/webor2006/p/11142839.html,如下:
因為咱們每個數組都申請的1M,肯定是超出標准區域的50%,所以當成了巨大的區域了,所以日志中會有“Humongous”,繼續分析:
這里回顧一下理論:
其實它剛好對應之前咱們學習的G1 Young GC的步驟之一,如下:
其中Rset是干啥用的,這里回憶一下,都是在之前的理論中有提及到的:
它其實就對應G1 Young GC的這個流程:
對應G1 Young GC這個流程:
這塊在之前G1 Young GC中也有提及,如下:
這里再來回顧個之前的東東,就是gc常見的算法有:
而且在老年代中不可能使用這個復制算法,所以再回顧一下這個圖:
也就是對就G1 Young GC的最后一個步驟:
繼續分析:
也是來自於G1 Young GC中的理論,回憶一下:
這些其實都是global concurrent marking的過程,回憶一下:
最后看一下整個堆的信息:
以上就是對於第一個G1日志的大體的認識,有很多細節還待未來進行進一步挖掘。