2013-05-12 35 views
3

我試圖寫一些快速的東西,並不斷分配和釋放內存,使內存分配在性能方面很重要。Java的新關鍵字是否必須表示堆分配?

分配對象是否總是將它們分配給堆? JIT編譯是否確實喜歡任何類型的分配優化?

+1

您是否對您的應用程序進行了簡介,以確定堆分配速度太慢,還是您只是在做出假設? – 2013-05-12 09:35:18

+0

我的應用程序是矢量數學密集型的,我的Vector類是不可變的。 雖然我對分析工具並不是很熟悉,但我不知道該如何分配花費多少時間,所以我想我正在做假設(對於恥辱,嘿) – cabbagebot 2013-05-12 09:49:04

+0

如果您需要極高的性能,您可以使用Vector類邏輯並將其移植到C++,然後使用JNI與您的類進行集成。這具有打破平臺獨立性的缺點,但如果它只是一小段代碼就可以。您可以爲大多數平臺提供「官方」編譯版本,並將.cpp文件與您的應用程序一起發佈,以便異國平臺的用戶可以自行編譯該庫。 – 2013-05-12 09:57:09

回答

9

將分配了new的對象放置在堆上,但JIT/JVM 可能會優化它們以使用轉義分析進行堆棧。瞭解更多關於它in this article published on IBM developerWorks

虛擬機可以使用一個名爲逃逸分析技術,通過它們可以告訴大家,某些對象仍然侷限於單一線程的整個生命週期,而且壽命是由一個壽命爲界給定的堆棧幀。這些對象可以安全地分配到堆棧而不是堆上。

你不可能直接控制堆棧分配,就像你無法預測GC何時運行一樣。如果你真的需要對存儲機制進行如此深入的控制,唯一的方法就是使用C/C++。

無論如何,在過分複雜你的軟件之前請三思。我上面鏈接的論文的結論對內存管理非常明確:

JVM出奇地擅長弄清楚我們以前只假定開發人員可以知道的事情。通過讓JVM根據具體情況在堆棧分配和堆分配之間進行選擇,我們可以獲得堆棧分配的性能優勢,而不會讓程序員因爲是在堆棧上還是在堆上分配而苦惱。

這並不意味着您永遠不需要對內存進行細粒度的控制,但是在大多數情況下,JVM可以優於一般程序員。

+0

啊,非常好,謝謝!我想知道是否存在監測這種情況的工具。不過,我很懷疑。 – cabbagebot 2013-05-12 09:47:13

+0

@cabbagebot我從來沒有嘗試過,但[VisualVM](http://visualvm.java.net/)可以幫助你。 – 2013-05-12 09:51:07

2

JLS說new分配一個新的對象。 JLS 12.5:

「當評估類實例創建表達式(第15.9節)導致類實例化時,會顯式創建新的類實例。

JLS並未說明對象的分配位置。如果編譯器可以推斷(通過轉義分析)可達性規則允許在堆棧上分配一個對象,那麼這是允許的。

通常將JLS讀爲允許優化,其效果無法通過觀察執行程序的結果來檢測。顯然,最新版本的Java 7,執行的優化之一涉及優化異常創建/拋出/ catch代碼並用無條件跳轉語句(或類似的...)替換它。在某些情況下,這種優化涉及優化掉一個明確的new陳述。

總之,new表達通常導致堆分配,但有時對象在棧上分配,並且有時分配被完全優化掉。

相關問題