簡體   English   中英

Java 非阻塞內存分配

[英]Java nonblocking memory allocation

我在某處讀到 java 可以用大約 12 條機器指令為對象分配內存。 這對我來說印象非常深刻。 據我了解,JVM 使用的技巧之一是分塊預分配內存。 這有助於最大限度地減少對操作系統的請求數量,我猜這是非常昂貴的。 但即使是 CAS 操作在現代處理器上也可能花費高達 150 個周期。

那么,誰能解釋一下 java 中內存分配的實際成本以及 JVM 使用哪些技巧來加速分配?

JVM 為每個線程預先分配一塊內存區域(TLA 或線程局部區域)。 當線程需要分配內存時,它將在該區域內使用“Bump the pointer allocation”。 (如果“空閑指針”指向地址10,並且要分配的對象大小為50,那么我們只需將空閑指針撞到60,並告訴線程它可以為對象使用10到59之間的內存) .

最好的技巧是分代垃圾收集器。 這可以保持堆不碎片化,因此分配內存會增加指向可用空間的指針並返回舊值。 如果內存耗盡,垃圾收集復制對象並以這種方式創建一個新的未碎片堆。

由於不同的線程必須同步指向空閑內存的指針,如果增加它,它們會預先分配塊。 所以一個線程可以分配新的內存,沒有鎖。

所有這些都在這里有更詳細的解釋: http : //java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

JVM 沒有單一的內存分配器。 IIRC Sun 的 JVM 和 IBM 的托管內存不同。 然而,通常 JVM 的操作方式是它最初會分配一塊內存,該段將小到足以存在於處理器緩存中,從而使所有訪問都非常快。

當應用程序創建對象時,對象將從該段中獲取內存。 段內的對象分配只是指針運算。

最初,新生成的段的偏移地址為零。 分配的第一個對象的“地址”(實際上是段的偏移量)為零。 當您分配對象時,內存管理器將知道對象有多大,在段內分配那么多空間(例如 16 字節),然后將它的“偏移地址”增加該數量,這意味着內存分配非常快,它只是指針算術。

Sun 有一份白皮書JavaHotSpot™ 虛擬機中的內存管理,IBM 曾經在 ibm.com/developerworks 上有很多東西

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM