【问题标题】:How many threads does the JVM fork when it is started?JVM 启动时会分叉多少个线程?
【发布时间】:2012-03-28 22:11:52
【问题描述】:

我只是想避免上下文切换,因为它会引入很多延迟。因此,如果我的想法正确,我希望每个处理器最多有一个线程。如果处理器支持虚拟并行(我认为是超线程!),那么我可以拥有双倍的线程数。

例如:4 个超线程处理器 = 最多 8 个线程。

当然,操作系统也需要处理器,所以我可能在这里太天真了。

无论如何,知道 JVM 在启动时创建的线程数是一个好的开始。

【问题讨论】:

  • 是的,你有点天真。 GC 总是会导致一些延迟,不管你有多少 CPU,尽管一些 GC 算法可以在多处理器系统中减少它。如果您想要保证低延迟,请避免使用 Java。 (最好是所有非实时操作系统。)
  • 稍微偏离主题,因此发表评论。 “所以如果我的想法是正确的,我希望每个处理器最多有一个线程”这实际上并不像你想象的那么好,除非你的线程将一直 100% 工作并且永远不会锁定,等待 I/O或其他任何东西。当然你不应该过度使用它,但在大多数情况下,试图将线程数保持在与内核或硬件线程数一样低的结果只是不会让你充分利用 CPU。
  • “我只是想避免上下文切换,因为它会引入很多延迟”。可以?你量过吗?
  • @EJP - 是的,上次我查看时,上下文切换是为了减少延迟,(好吧,IO 延迟,无论如何)。

标签: java multithreading concurrency parallel-processing real-time


【解决方案1】:

JVM 只启动 1 个用户线程,也称为“主”线程。还有其他线程在后台运行,例如垃圾收集器、编译器、优化器、终结器等。

快速浏览一个无关紧要的应用程序的线程转储:

public static void main(String[] args) throws Exception {
    Thread.sleep(100000);
}

演出:

"Low Memory Detector" daemon prio=5 tid=7f810c801000]
"C2 CompilerThread1" daemon prio=9 tid=7f810c800000
"C2 CompilerThread0" daemon prio=9 tid=7f8107037000
"Signal Dispatcher" daemon prio=9 tid=7f8107036000
"Surrogate Locker Thread (Concurrent GC)" daemon prio=5 tid=7f8107801000 
"Finalizer" daemon prio=8 tid=7f810882a000 nid=0x1118cb000 
"Reference Handler" daemon prio=10 tid=7f8108829000 nid=0x1117c8000 
"main" prio=5 tid=7f8104801000 nid=0x109a52000 waiting on condition
"VM Thread" prio=9 tid=7f8108824800 nid=0x1116c5000 runnable 
"Gang worker#0 (Parallel GC Threads)" prio=9 tid=7f8104802800
"Gang worker#1 (Parallel GC Threads)" prio=9 tid=7f8104803000 
"Gang worker#2 (Parallel GC Threads)" prio=9 tid=7f8104803800 
"Gang worker#3 (Parallel GC Threads)" prio=9 tid=7f8107800000 
"Gang worker#4 (Parallel GC Threads)" prio=9 tid=7f8108800000 
"Gang worker#5 (Parallel GC Threads)" prio=9 tid=7f8107000800
"Gang worker#6 (Parallel GC Threads)" prio=9 tid=7f8107001000
"Gang worker#7 (Parallel GC Threads)" prio=9 tid=7f8107002000 
"Concurrent Mark-Sweep GC Thread" prio=9 tid=7f810701c000
"Gang worker#0 (Parallel CMS Threads)" prio=9 tid=7f81090c3000
"Gang worker#1 (Parallel CMS Threads)" prio=9 tid=7f810701b800
"VM Periodic Task Thread" prio=10 tid=7f810c812800 
"Exception Catcher Thread" prio=10 tid=7f8104801800

【讨论】:

  • 假设我想通过为每个线程提供一个处理器来避免上下文切换,是否值得知道除了这个单个用户线程之外 JVM 创建的线程总数?
  • 我不这么认为@JohnPristine。如果您问应该运行多少用户线程来“最大化”您的应用程序,那么我会为垃圾收集器分配 1 个。其余的都不应该占用任何重要的时间。
  • 当然,取决于您在 finalize() 方法中添加的内容(例如无限循环 :)),终结器线程本身也可以占用整个内核。
  • 嗯,当然@biziclop。尽管不赞成使用finalize()securecoding.cert.org/confluence/display/java/…
  • 我当然不赞成。 :) 只是展示了 OP 的方法是多么脆弱。
猜你喜欢
  • 2021-11-22
  • 1970-01-01
  • 2021-09-12
  • 2021-05-31
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多