簡體   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