我一直在阅读(例如here和here),对于-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
答案 0 :(得分:0)
如果启用了串行GC,则线程无法分配内存用于执行垃圾收集。
如果在此类GC期间进行混合线程转储,则可以观察到JVM GC相关代码正在从Java代码中的分配尝试中递归执行。
这是单线程GC算法的具体内容。多线程GC的所有变体都使用GC工作者的专用线程池。