亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何確定我使用哪種 GC?

如何確定我使用哪種 GC?

慕容708150 2022-07-06 19:14:24
我沒有指定任何 GC,我認為我的 JVM 默認沒有啟用任何 GC。當然我知道OpenJDK8默認使用ParallelGC,但我認為它應該可以通過命令行打印,像這樣:java -XX:+PrintFlagsFinal|grep Use|grep GC我希望輸出包含 bool UseParallelOldGC = true {product}但它不是:     bool ParGCUseLocalOverflow                     = false                               {product}     bool UseAdaptiveGCBoundary                     = false                               {product}     bool UseAdaptiveSizeDecayMajorGCCost           = true                                {product}     bool UseAdaptiveSizePolicyWithSystemGC         = false                               {product}     bool UseAutoGCSelectPolicy                     = false                               {product}     bool UseConcMarkSweepGC                        = false                               {product}     bool UseDynamicNumberOfGCThreads               = false                               {product}     bool UseG1GC                                   = false                               {product}     bool UseGCLogFileRotation                      = false                               {product}和java -XX:+PrintCommandLineFlags -version我希望輸出包含:XX:+UseParallelGC但也不是:-XX:InitialHeapSize=460493056 -XX:MaxHeapSize=7367888896 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops .我的 JVM 選項:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -verbose:gc -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime.上面的輸出表明沒有啟用任何 GC(我想是這樣),我對這種情況感到非常困惑。日志顯示 JVM 堆分為new和tenured,但沒有打印 GC 類型。可悲的是,我也不能jmap -heap {pid}用來獲取 GC 類型,因為 jmap 在我的環境中沒有這個選項(-heap)。所以我想知道:哪個 GC 是我真正使用的?命令行選項(-XX:+PrintCommandLineFlags和-XX:+PrintFlagsFinal)輸出信息是否正確?我的環境:k8s+docker,Alpine OpenJKD8
查看完整描述

2 回答

?
嗶嗶one

TA貢獻1854條經驗 獲得超8個贊

jcmd <pid> VM.flags應該有幫助。


例如


$ /usr/java/jdk1.8.0_202/bin/java Test

...

$ jcmd 28815 VM.flags

28815:

-XX:CICompilerCount=3 -XX:InitialHeapSize=266338304 -XX:MaxHeapSize=4257218560 -XX:MaxNewSize=1418723328 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88604672 -XX:OldSize=177733632 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC

最后打印的標志-XX:+UseParallelGC即使沒有明確指定。


然后,如果我運行將 G1 作為默認收集器的 JDK 11,我將得到以下輸出:


$ /usr/java/jdk11.0.2/bin/java Test

...

$ jcmd 28862 VM.flags

28862:

-XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1ConcRefinementThreads=4 -XX:G1HeapRegionSize=1048576 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=266338304 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4257218560 -XX:MaxNewSize=2554331136 -XX:MinHeapDeltaBytes=1048576 -XX:NonNMethodCodeHeapSize=5830092 -XX:NonProfiledCodeHeapSize=122914074 -XX:ProfiledCodeHeapSize=122914074 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC

現在最后打印的選項是-XX:+UseG1GC.


如果由于某種原因你沒有jcmd可用的,你可以嘗試jattach哪個是輕量級的獨立替代品jcmd:


$ jattach 28862 jcmd VM.flags

更新


如果沒有-XX:Use*GC打印任何標志,則表示使用了 Serial GC。這只發生在 JDK 8 和更早版本上。從 JDK 9 開始,Use*GCJVM 會自動設置其中一個標志。有關詳細信息,請參閱JDK-8068582。


查看完整回答
反對 回復 2022-07-06
?
Helenr

TA貢獻1780條經驗 獲得超4個贊

bool問題是,當您真正想要一個名稱時,您正在查看類型的 JVM 選項。這不是你的錯,JVM 的設計者決定給不同的垃圾收集器命名,但提供看起來像布爾選項的控件。


因此,即使所有這些選項都是false,也有一個垃圾收集器,但這些選項不足以獲得它的名字。但另一方面,無論如何,大多數名稱都不足以描述這些垃圾收集器的作用,或者它們與其他算法的不同之處。


JDK8默認使用ParallelGC并不完全正確;正如這個答案所描述的,該算法是由一些啟發式選擇的,但是,在大多數情況下,你最終會選擇 ParallelGC。


使用以下代碼


Object flags = ManagementFactory.getPlatformMBeanServer().invoke(

    ObjectName.getInstance("com.sun.management:type=DiagnosticCommand"),

    "vmFlags", new Object[] { null }, new String[] { "[Ljava.lang.String;" });

for(String f: ((String)flags).split("\\s+"))

    if(f.contains("GC")) System.out.println(f);

for(GarbageCollectorMXBean gc: ManagementFactory.getGarbageCollectorMXBeans())

    System.out.printf("%-20s%s%n", gc.getName(), Arrays.toString(gc.getMemoryPoolNames()));

我明白了


> jdk1.8.0_162\bin\java ...

-XX:+UseParallelGC

PS Scavenge         [PS Eden Space, PS Survivor Space]

PS MarkSweep        [PS Eden Space, PS Survivor Space, PS Old Gen]

在我的機器上,所以在沒有選項的情況下運行確實在這個環境中選擇了 ParallelGC。但請注意報告的名稱“PS Scavenge”和“PS MarkSweep”,它們突出了選項和名稱的另一個問題:典型配置考慮有兩種垃圾收集算法,一種用于次要 gc,一種用于主要 gc。


當我嘗試時-XX:-UseParallelGC,我得到


> jdk1.8.0_162\bin\java -XX:-UseParallelGC ...

-XX:+UseParallelGC

PS Scavenge         [PS Eden Space, PS Survivor Space]

PS MarkSweep        [PS Eden Space, PS Survivor Space, PS Old Gen]

這演示了 JVM 選項的問題,如下所示boolean:我無法關閉它們,因為 JVM 需要一個實際的其他垃圾收集器來選擇。

所以要關閉并行,你可以使用-XX:+UseSerialGC:


> jdk1.8.0_162\bin\java -XX:+UseSerialGC ...

-XX:+UseSerialGC

Copy                [Eden Space, Survivor Space]

MarkSweepCompact    [Eden Space, Survivor Space, Tenured Gen]

為了比較


> jdk1.8.0_162\bin\java -XX:+UseConcMarkSweepGC ...

-XX:+UseConcMarkSweepGC

-XX:+UseParNewGC

ParNew              [Par Eden Space, Par Survivor Space]

ConcurrentMarkSweep [Par Eden Space, Par Survivor Space, CMS Old Gen]

請注意這兩種算法中的每一種如何與一個選項相關聯,但指定一個選項可以選擇兩種垃圾收集算法。


> jdk-9.0.4\bin\java ...

-XX:ConcGCThreads=2

-XX:+UseG1GC

G1 Young Generation [G1 Eden Space, G1 Survivor Space]

G1 Old Generation   [G1 Eden Space, G1 Survivor Space, G1 Old Gen]


> jdk-11.0.1\bin\java ...

-XX:ConcGCThreads=2

-XX:GCDrainStackTargetSize=64

-XX:+UseG1GC

G1 Young Generation [G1 Eden Space, G1 Survivor Space, G1 Old Gen]

G1 Old Generation   [G1 Eden Space, G1 Survivor Space, G1 Old Gen]


> jdk-11.0.1\bin\java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC ...

-XX:+UseEpsilonGC

Epsilon Heap        [Epsilon Heap]

因此,如果嘗試獲取相關Use…GC boolean選項的代碼(即上面代碼的第一部分,使用非標準com.sun.management:type=DiagnosticCommandMBean)找不到任何選項,您可以嘗試使用 報告的垃圾收集器名稱getGarbageCollectorMXBeans(),但正如您所見,這些名稱與 JVM 選項的名稱不匹配,因此您必須知道這些名稱是如何關聯的。


但歸根結底,這些名稱都不是真正的描述性名稱,所以它們只有在您已經知道這些名稱背后的內容時才有用……


查看完整回答
反對 回復 2022-07-06
  • 2 回答
  • 0 關注
  • 277 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號