2017-04-25 46 views
0

JVM負責爲基於對象大小使用Java中的new關鍵字創建的對象分配堆內存。 內存分配如何在內部工作。 JVM是否維護一個指向下一個足夠大的可用內存塊的指針並返回它,或者它通過系統調用將內存分配的責任委託給OS,就像在C內部調用brk()中的malloc一樣?Java新的關鍵字內部結構

+1

這取決於JRE的實現。 – SLaks

+1

這個邏輯是每個JVM實現的內部。 – dasblinkenlight

+0

我認爲你對此太深刻了。你不需要這些知識就可以有效地發揮作用,它可以在兔子洞的很長一段路上。 – solstinger

回答

0

它依賴於JVM,它是一個實現細節。但它通常通過TLAB - 線程本地分配緩衝區完成,因爲它是一個簡單的指針凹凸,所以更快,然後malloc。這是一個非常簡單的解釋。

0

的規範的Java實現使用的存儲器分配的代戰略。

https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/memman.html#wp1089132 http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf

對象在「堆」存儲器,其被劃分爲兩個區域稱爲「代」分配。有一個「年輕一代」地區被進一步分爲「伊甸園」(又名「託兒所」)和兩個「倖存者空間」。還有一個「舊」或「終身」的世代區域,基本上包含了年輕一代所沒有的所有堆。

對象通常在伊甸第一分配。 「大」對伊甸園來說太大了的東西進入了老一代。

當伊登得到充分,所有的「活」的對象,那些仍然通過在程序中有一定的參考到達,被複制到第一生存空間,然後伊甸被刪除,指針釋放伊甸園空間設置爲空間的開始。

對象分配是簡單地指定伊甸的當前「頂部」作爲新的對象的地址,並以釋放伊甸存儲器中的指針被增加的對象的尺寸的問題。在現代計算機上這需要10納秒。沒有相當於「免費」的東西,因爲單個對象永遠不會被釋放;整個堆的部分被簡單地擦除並且自由區域指針被重置。 當第一個倖存者空間已滿時,JVM將其所有活動對象和Eden複製到另一個倖存者空間中。伊甸園和第一個倖存者空間被抹去,他們的指針重置。現在其他倖存者空間變成「第一」,舊的「第二」,並且該過程重複。

這是非常迅速的,因爲死的對象是不被跟蹤或標記,並精心編寫的程序往往有許多相對較小的天體,其中大多數都活不長。

當物體做相處時間長了,他們得到「提升」了年輕一代向年老代,收集不經常使用較慢的算法。與年輕一代相比,老年人往往死亡的速度較慢,而當他們這樣做時,他們的空間就會成爲中間某處空閒空間的「洞」。舊一代垃圾收集通常包括將活動對象彼此靠近以將可用內存塊合併爲較大的塊。

這只是一個表面的劃傷。還有更多要研究。