繁体   English   中英

对象创建是多线程环境中Java的瓶颈吗?

[英]Is object creation a bottleneck in Java in multithreaded environment?

基于以下理解:

在堆栈中还是在堆中分配变量引用的位置?

我想知道因为所有对象都是在公共堆上创建的。 如果多个线程创建对象然后为了防止数据损坏,必须进行一些必须发生的序列化以防止多个线程在相同位置创建对象。 现在,有了大量的线程,这种序列化将导致一个巨大的瓶颈。 Java如何避免这个瓶颈? 或者我错过了什么?

任何帮助赞赏。

现代VM实现为每个线程保留堆上的自己区域以创建对象。因此,只要该区域未满(然后垃圾收集器移动幸存的对象)就没有问题。

进一步阅读: TLAB如何在Sun的JVM中运行。 Azul的VM使用稍微不同的方法(查看“新的线程和堆栈布局”),文章展示了JVM可能在幕后执行的一些技巧,以确保现在的Java速度。

主要思想是保持每个线程(非共享)区域分配新对象,就像使用C / C ++在堆栈上分配一样。 复制垃圾收集非常快速地释放短期对象,少数幸存者(如果有的话)被移动到不同的区域。 因此,创建相对较小的对象非常快并且无

无锁分配非常重要,特别是因为问题涉及multithreaded environment 它还允许存在真正的无锁算法。 即使算法本身是无锁的,但新对象的分配是同步的,整个算法也是有效同步的,并且最终可扩展性较差。 java.util.concurrent.ConcurrentLinkedQueue基于Maged M. Michael Michael L. Scott的工作是一个典型的例子。


如果一个对象被另一个线程引用会发生什么? (由于讨论要求)

该对象(称为A )将被移动到一些“幸存者”区域。 幸存区域的检查频率低于ThreadLocal区域。 它包含,如名称所示,其引用设法逃脱的对象,或特别是A设法保持活着。 复制(移动)部分发生在某些“安全点”(安全点排除了正确的JIT代码),因此垃圾收集器确保该对象未被引用。 更新对象的引用,发布必要的内存围栏,应用程序(java代码)可以继续。 进一步阅读这个简单的场景

对于非常感兴趣的读者,如果可能的话,咀嚼它:非常先进的Pauseless GC算法

不会.JVM有各种各样的技巧,以避免在“新”时出现任何类型的简单序列化。

有时。 我写了一个递归方法,生成整数排列并从中创建对象。 该方法的多线程版本(来自root = task的每个分支,但并发线程数限制为核心数)并不快。 并且CPU负载不高。 任务没有共享任何对象。 从两种方法中删除对象后,多线程方法的速度提高了约4倍(6个核心)并使用了100%的CPU。 在我的测试用例中,这些方法产生了大约4,500,000个排列,每个任务1500个。 我认为TLAB不起作用,因为它的空间有限(参见: Thread Local Allocation Buffers )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM