[英]Simple Java example runs with 14 threads. Why?
以下簡單的Java代碼:
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("Start");
Thread.sleep(5000);
System.out.println("Done");
}
}
運行使用14個線程。 我知道有些GC線程在后台運行,但其他的是什么? 為什么有那么多線程? 我在Java 1.6.0_26上使用Gentoo Linux。 使用Eclipse的編譯器或javac進行編譯並沒有什么區別(在Eclipse中以調試模式運行它會增加3個線程,但這可能是合理的)。
我的JVM(1.6.0_26)默認生成更多線程。 大多數都有相當具有描述性的名稱暗示其目的:
"Attach Listener" daemon prio=10 tid=0x0000000041426800 nid=0x2fb9 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Low Memory Detector" daemon prio=10 tid=0x00007f512c07e800 nid=0x2fa3 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=10 tid=0x00007f512c07b800 nid=0x2fa2 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=10 tid=0x00007f512c078800 nid=0x2fa1 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=10 tid=0x00007f512c076800 nid=0x2fa0 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=10 tid=0x00007f512c05a000 nid=0x2f9f in Object.wait() [0x00007f512b8f7000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007c14b1300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x00000007c14b1300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x00007f512c058000 nid=0x2f9e in Object.wait() [0x00007f512b9f8000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007c14b11d8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x00000007c14b11d8> (a java.lang.ref.Reference$Lock)
"main" prio=10 tid=0x0000000041401800 nid=0x2f94 waiting on condition [0x00007f5135735000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at Main.main(Main.java:5)
"VM Thread" prio=10 tid=0x00007f512c051800 nid=0x2f9d runnable
"GC task thread#0 (ParallelGC)" prio=10 tid=0x0000000041414800 nid=0x2f95 runnable
"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f512c001000 nid=0x2f96 runnable
"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f512c002800 nid=0x2f97 runnable
"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f512c004800 nid=0x2f98 runnable
"GC task thread#4 (ParallelGC)" prio=10 tid=0x00007f512c006800 nid=0x2f99 runnable
"GC task thread#5 (ParallelGC)" prio=10 tid=0x00007f512c008000 nid=0x2f9a runnable
"GC task thread#6 (ParallelGC)" prio=10 tid=0x00007f512c00a000 nid=0x2f9b runnable
"GC task thread#7 (ParallelGC)" prio=10 tid=0x00007f512c00c000 nid=0x2f9c runnable
"VM Periodic Task Thread" prio=10 tid=0x00007f512c089000 nid=0x2fa4 waiting on condition
顯然,大多數線程都與內存處理有關:有8個垃圾收集器線程,還有低內存檢測器。 Finalizer
和Reference Handler
聽起來像是他們也參與了內存管理。
C2 CompilerThread0/1
幾乎肯定與即時編譯有關。
VM Periodic Task Thread
在這里解釋: 什么是“VM Periodic Task Thread”?
至於其余線程的確切目的,我不確定。
我使用jvisualvm
制作了這個截圖。 運行線程(在eclipse中):
運行與* .jar文件相同的程序; 只有4個守護程序線程和1個活動線程正在運行。
這可能無法解決問題,但至少有助於了解正在發生的事情。 要獲得准確的線程示例,請在應用程序中獲取列表表單。 (而不是從調試工具。)
JVM沒有儀表
JVM w / Instrumentation(jconsole)
實驗
public class JVM {
public static void main(String... args) throws InterruptedException {
for (java.util.Enumeration<?> e = System.getProperties().propertyNames(); e.hasMoreElements();) {
String prp = (String) e.nextElement();
if (prp.startsWith("java.vm") || prp.startsWith("os.")) {
System.out.format("[%s]=%s%n", prp, System.getProperty(prp));
}
}
java.text.DateFormat df = new java.text.SimpleDateFormat("HH:mm:ss.SSS");
for(;;) {
System.out.format("%s Sampling current threads...%n", df.format(new java.util.Date()));
java.util.Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces();
System.out.format("> Thread Count: %d%n", stacks.size());
for (java.util.Map.Entry<Thread, StackTraceElement[]> entry : stacks.entrySet()) {
Thread thread = entry.getKey();
StackTraceElement[] stack = entry.getValue();
System.out.format("> Thread: %s%n", thread.getName());
// Throwable t = new Throwable("Thread: " + thread.getName());
// t.setStackTrace(stack);
// t.printStackTrace(System.out);
}
java.util.concurrent.TimeUnit.SECONDS.sleep(10);
}
}
}
產量
[java.vm.version]=16.2-b04
[java.vm.vendor]=Sun Microsystems Inc.
[java.vm.name]=Java HotSpot(TM) Client VM
[java.vm.specification.name]=Java Virtual Machine Specification
[os.arch]=x86
[java.vm.specification.vendor]=Sun Microsystems Inc.
[os.name]=Windows XP
[os.version]=5.1
[java.vm.specification.version]=1.0
[java.vm.info]=mixed mode, sharing
14:03:49.199 Sampling current threads...
> Thread Count: 5
> Thread: main
> Thread: Reference Handler
> Thread: Signal Dispatcher
> Thread: Attach Listener
> Thread: Finalizer
14:03:59.200 Sampling current threads...
> Thread Count: 10
> Thread: main
> Thread: JMX server connection timeout 12
> Thread: RMI TCP Connection(1)-10.1.100.40
> Thread: RMI TCP Connection(2)-10.1.100.40
> Thread: Finalizer
> Thread: Reference Handler
> Thread: RMI Scheduler(0)
> Thread: Signal Dispatcher
> Thread: RMI TCP Accept-0
> Thread: Attach Listener
通常運行Java程序時,它在虛擬機上運行。 您看到的一些線程是針對VM的 - 無論是為了VM的運行還是為了提高效率(編譯器線程 - 當找到潛在的優化候選者時(稱為“熱點”),這些線程將將它從Java Byte代碼編譯為運行JVM的平台的機器代碼。
大多數其他線程用於內存管理。 有很多可以提供更好的用戶體驗(如果垃圾收集完成得更快,UI /界面將掛起更短的時間)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.