开发者

Simple Java example runs with 14 threads. Why?

开发者 https://www.devze.com 2023-04-11 21:14 出处:网络
The following trivial Java code: public class Main { public static void main(String[] args) throws InterruptedExceptio开发者_如何学JAVAn {

The following trivial Java code:

public class Main {
    public static void main(String[] args) throws InterruptedExceptio开发者_如何学JAVAn {
        System.out.println("Start");
        Thread.sleep(5000);
        System.out.println("Done");
    }
}

Runs using 14 threads. I know that theres some GC thread running in the background, but what are the others for? Why are there so many threads? I'm on Gentoo Linux with Java 1.6.0_26. Compiling with Eclipse's compiler or javac doesn't make a difference(Running it in Eclipse in debug mode adds 3 more threads to it, but that's probably justified).


My JVM (1.6.0_26) spawns even more threads by default. Most have pretty descriptive names that hint at their purpose:

"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 

Clearly, most of the threads have to do with memory handling: there are 8 garbage collector threads, plus the low memory detector. Finalizer and Reference Handler sound like they are also involved in memory management.

C2 CompilerThread0/1 almost certainly have to do with just-in-time compilation.

VM Periodic Task Thread is explained here: What is the "VM Periodic Task Thread"?

As to the exact purpose of the remaining threads, I am not sure.


I made this Screenshot using jvisualvm. Running threads (in eclipse):

Simple Java example runs with 14 threads. Why?

Running the same program as *.jar file; there are only 4 daemon threads and 1 live thread running.


This may not answer the question, but at least help understand what's going on. To get an accurate sample of the threads, get the list form within your app. (Instead of from the debugging tools.)

JVM w/o Instrumentation

  • Thread: main
  • Thread: Reference Handler
  • Thread: Signal Dispatcher
  • Thread: Attach Listener
  • Thread: Finalizer

JVM w/ Instrumentation (jconsole)

  • 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

Experiment

  1. Execute the following code
  2. Launch jconsole and connect to that jvm
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);
    }
  }
}

Output

[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


When you typically run a Java Program, it runs on a virtual machine. Some of the threads you see are for the VM -- either for the functioning of the VM or to increase the efficiency (the compiler threads -- when a potential candidate for optimization is found (called a "Hot spot"), these threads will compile it from Java Byte code to machine code for the platform on which the JVM is running).

Most of the other threads are for memory management. There are so many to give a better user experience (the UI / interface will hang for lesser time if garbage collection finishes faster).

0

精彩评论

暂无评论...
验证码 换一张
取 消