创建线程很昂贵。但是为什么价格昂贵呢?当创建Java线程使创建过程变得昂贵时,究竟发生了什么?我认为该说法是正确的,但是我只是对JVM中的线程创建机制感兴趣。
线程生命周期开销。线程创建和拆除不是免费的。实际开销因平台而异,但是线程创建会花费时间,从而在请求处理中引入延迟,并且需要JVM和OS进行某些处理活动。如果请求是频繁且轻量的(如在大多数服务器应用程序中一样),则为每个请求创建一个新线程可能会消耗大量计算资源。
Java线程的创建非常昂贵,因为其中涉及大量工作:
所有这些东西的成本是特定于平台的,但是在我遇到过的任何Java平台上,它们都不便宜。
谷歌搜索发现我有一个旧的基准,该基准报告说,在运行2002老式Linux的2002老式双处理器Xeon上,在Sun Java 1.4.1上线程创建速率约为4000每秒。一个更现代的平台将提供更多的数据……而我无法评论该方法论……但至少,它为可能创建线程的成本提供了保证。
彼得·劳瑞(Peter Lawrey)的基准测试表明,从绝对意义上讲,如今的线程创建速度显着提高,但尚不清楚其中有多少是由于Java和/或操作系统的改进或更高的处理器速度所致。但是,如果你使用线程池,而不是每次都创建/启动一个新线程,那么他的数据仍然表明改进了150倍以上。(他指出这都是相对的…)
(以上假定“本地线程”而不是“绿色线程”,但是现代JVM出于性能原因都使用本地线程。绿色线程创建起来可能更便宜,但你可以在其他方面为此付出代价。)
我做了一些挖掘工作,以了解如何真正分配Java线程的堆栈。对于Linux上的OpenJDK 6,线程堆栈是通过调用分配给pthread_create
创建本地线程的。(JVM不会传递pthread_create预分配的堆栈。)
然后,在pthread_create
栈内通过调用分配mmap如下:
mmap(0, attr.__stacksize,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
根据man mmap
,该MAP_ANONYMOUS
标志使内存初始化为零。
因此,即使并非必须(根据JVM规范)将新的Java线程栈置零,但实际上(至少对于Linux上的OpenJDK 6)将它们置零。
我试图通过拆分列表来检查元素是否在字符串中: `公共类ParallelSearchComment扩展了RecursiveTask{private static final long serialVersionUID=1L; `
我编写了代码示例: 每100毫秒提交一个新任务(总任务量-20)。每个任务持续时间-0.5秒。因此,可以并行执行5个任务,最佳执行时间为:20*100 500=2.5秒,池应创建5个线程 但我的实验显示为9.6秒。我打开jsvisualvm查看池创建了多少线程,我看到只创建了一个线程: 请更正我的线程池配置不正确的地方。
问题内容: 我对Java真的很陌生,我读到Java 非常昂贵。我只想知道什么是昂贵的,它又如何昂贵? 谢谢。 问题答案: 也许还没有你想的那么糟 它曾经是可怕的(这可能就是您读到它“非常昂贵”的原因)。这些模因可能需要很长时间才能消失 由于涉及缓存刷新和失效的规则,因此Java语言中的同步块通常比许多平台提供的关键部分功能更为昂贵,而这些平台通常使用原子的“测试并设置位”机器指令来实现。即使程序仅
问题内容: 我写了一个Java程序,它会休眠一段时间: 我使用以下程序运行该程序: 我检查了Ubuntu创建的运行它的过程: 这些命名的线程(即轻量级进程){java} 是为什么创建的? 是否有可能使用某些命令从shell运行哪些程序? 哪些进程(和LWP)正在运行JVM? 哪些进程(和LWP)正在运行我的Java程序? 问题答案: 所有这些线程都属于JVM。 运行以获取线程列表。 这nid是操作
下面的代码继续创建线程,即使队列是空的...直到最终发生OutOfMemory异常。如果我用一个常规的foreach替换并行。Foreach,这不会发生。有人知道为什么会发生这种情况吗?
本文向大家介绍线程,进程,然后线程创建有很大开销,怎么优化?相关面试题,主要包含被问及线程,进程,然后线程创建有很大开销,怎么优化?时的应答技巧和注意事项,需要的朋友参考一下 考察点:多线程 可以使用线程池。