-XX:+ UseSerialGC使用主线程进行GC

时间:2018-03-15 12:44:32

标签: java multithreading memory memory-management garbage-collection

我一直在阅读(例如herehere),对于-XX:+UseSerialGC垃圾收集器,只有单个线程用于垃圾收集。但目前尚不清楚这个"单线程"是main线程或不同的单个GC线程。

所以,我带了一个带有和没有-XX:+UseSerialGC的线程转储,对我来说,看起来当使用这个选项时,GC由main线程执行,因为我没有看到任何GC线程(如"GC task thread#0 (ParallelGC)")当我使用-XX:+UseSerialGC时。

对JVM和GC有良好经验和知识的人,请确认或纠正我的理解。

没有-XX:+UseSerialGC

2018-03-15 17:52:36
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001d88d800 nid=0x1e64 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000001d809000 nid=0x2598 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000001d806800 nid=0x30d8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001d801800 nid=0x1338 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001d800800 nid=0x306c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001c18b800 nid=0x323c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001c16d000 nid=0x2dd0 in Object.wait() [0x000000001d7fe000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000076f2011d8> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x000000076f2011d8> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x000000001c12b800 nid=0x28a8 in Object.wait() [0x000000001d61f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000076f208178> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    - locked <0x000000076f208178> (a java.lang.ref.Reference$Lock)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"main" #1 prio=5 os_prio=0 tid=0x000000000223d000 nid=0x3174 runnable [0x00000000026ef000]
   java.lang.Thread.State: RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:326)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    - locked <0x000000076f2240c0> (a java.io.BufferedOutputStream)
    at java.io.PrintStream.write(PrintStream.java:482)
    - locked <0x000000076f201258> (a java.io.PrintStream)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
    - locked <0x000000076f201218> (a java.io.OutputStreamWriter)
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
    at java.io.PrintStream.write(PrintStream.java:527)
    - locked <0x000000076f201258> (a java.io.PrintStream)
    at java.io.PrintStream.print(PrintStream.java:669)
    at com.learn.stackoverflow.general.memory.GCThreadCount.main(GCThreadCount.java:12)

"VM Thread" os_prio=2 tid=0x000000001c124000 nid=0x25e0 runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002256000 nid=0x3198 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002257800 nid=0x1ed4 runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002259000 nid=0x199c runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000225a800 nid=0x2870 runnable 

"VM Periodic Task Thread" os_prio=2 tid=0x000000001d8ad800 nid=0x1fa0 waiting on condition 

JNI global references: 8


With 2018-03-15 17:52:36
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001d88d800 nid=0x1e64 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000001d809000 nid=0x2598 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000001d806800 nid=0x30d8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001d801800 nid=0x1338 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001d800800 nid=0x306c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001c18b800 nid=0x323c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001c16d000 nid=0x2dd0 in Object.wait() [0x000000001d7fe000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000076f2011d8> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x000000076f2011d8> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x000000001c12b800 nid=0x28a8 in Object.wait() [0x000000001d61f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000076f208178> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    - locked <0x000000076f208178> (a java.lang.ref.Reference$Lock)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"main" #1 prio=5 os_prio=0 tid=0x000000000223d000 nid=0x3174 runnable [0x00000000026ef000]
   java.lang.Thread.State: RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:326)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    - locked <0x000000076f2240c0> (a java.io.BufferedOutputStream)
    at java.io.PrintStream.write(PrintStream.java:482)
    - locked <0x000000076f201258> (a java.io.PrintStream)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
    - locked <0x000000076f201218> (a java.io.OutputStreamWriter)
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
    at java.io.PrintStream.write(PrintStream.java:527)
    - locked <0x000000076f201258> (a java.io.PrintStream)
    at java.io.PrintStream.print(PrintStream.java:669)
    at com.learn.stackoverflow.general.memory.GCThreadCount.main(GCThreadCount.java:12)

"VM Thread" os_prio=2 tid=0x000000001c124000 nid=0x25e0 runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002256000 nid=0x3198 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002257800 nid=0x1ed4 runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002259000 nid=0x199c runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000225a800 nid=0x2870 runnable 

"VM Periodic Task Thread" os_prio=2 tid=0x000000001d8ad800 nid=0x1fa0 waiting on condition 

JNI global references: 8

使用-XX:+UseSerialGC

2018-03-15 17:54:47
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001351a000 nid=0x2388 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x0000000013492000 nid=0x2630 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x0000000013490000 nid=0x3084 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001348b000 nid=0x32cc waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000013489800 nid=0x3334 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000013488000 nid=0xcc0 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000013469800 nid=0x3144 in Object.wait() [0x000000001380f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000006c5a60d18> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x00000006c5a60d18> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000013422000 nid=0xf20 in Object.wait() [0x000000000259e000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000006c5a60ed0> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    - locked <0x00000006c5a60ed0> (a java.lang.ref.Reference$Lock)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"main" #1 prio=5 os_prio=0 tid=0x00000000022cd000 nid=0x332c runnable [0x000000000274f000]
   java.lang.Thread.State: RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:326)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    - locked <0x00000006c5a6e000> (a java.io.BufferedOutputStream)
    at java.io.PrintStream.write(PrintStream.java:482)
    - locked <0x00000006c5a60f20> (a java.io.PrintStream)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
    - locked <0x00000006c5a60ee0> (a java.io.OutputStreamWriter)
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
    at java.io.PrintStream.write(PrintStream.java:527)
    - locked <0x00000006c5a60f20> (a java.io.PrintStream)
    at java.io.PrintStream.print(PrintStream.java:669)
    at com.learn.stackoverflow.general.memory.GCThreadCount.main(GCThreadCount.java:12)

"VM Thread" os_prio=2 tid=0x0000000013419000 nid=0x13e8 runnable 

"VM Periodic Task Thread" os_prio=2 tid=0x0000000014311000 nid=0x3364 waiting on condition 

JNI global references: 8

1 个答案:

答案 0 :(得分:0)

如果启用了串行GC,则线程无法分配内存用于执行垃圾收集。

如果在此类GC期间进行混合线程转储,则可以观察到JVM GC相关代码正在从Java代码中的分配尝试中递归执行。

这是单线程GC算法的具体内容。多线程GC的所有变体都使用GC工作者的专用线程池。