2012-02-25 81 views
3

我想知道是否我們認爲Java擁有的堆棧分配大小(例如512k)是一個邏輯大小(意思是說,實際上我們使用的大於512k,包括所有的熱點開銷),或者是一個物理限制(意思是將堆棧中的所有Java分配的東西加起來不會超過512k)?Java的堆棧分配的大小是物理還是邏輯?

很難算出這個由測試,我會說,在我的其他職位是看出:Inferring a method's stack memory use in Java

我想某種資源,如果可能的話!

感謝

回答

2

我認爲物理和邏輯之間的區別是有點在這種情況下模糊。由於HotSpot會將您的代碼隨意地轉換爲本地代碼,並且結果可能取決於許多優化,因此可以認爲這兩個視圖都是正確的。

或者,人們可以說棧是物理的,但棧上的內容是可變的,並不總是很容易從正在執行的Java代碼中派生出來。例如,函數調用可以內聯或不內聯,因此從一個地方調用函數可能需要額外的堆棧空間,並且從另一個地方或另一個時間調用同一個函數可能不需要它或需要更少(或更多)。這在this document中被稱爲深入內聯。如果將參考推送到堆棧中,它們的大小也可能會有所不同(即使在64位JVM中也有可能會將參考壓縮到32位的技巧)。由於JIT編譯器異步工作,並根據代碼執行的分析數據做出一些決定,相同的代碼可能會有不同的性能,並且可能在不同的運行期間堆棧使用。

編輯: 垃圾收集,JIT編譯器等,在單獨的線程運行,因此他們用自己的調用堆棧,如果這就是你所說的「熱點架空」的意思。

+0

我會盡量讓自己更清楚一點。我一直在吸取JDK和HotSpot的代碼,並且我得出結論,例如,在進行方法調用時,會有這個大結構(JavaCallWrapper是它的名稱),它被創建爲充滿了所有這些各種信息,如參數,返回數據,線程信息等等。當然,只有這個結構存在的事實會增加更多顯而易見的數據(比如參數本身,返回數據,這個參數等等)。你會爲JVM定義的堆棧大小「計數」這個JavaCallWrapper嗎? – 2012-02-25 18:09:29

2

堆棧大小在實際使用之前使用虛擬內存。這意味着每個線程的堆棧大小可能爲1 MB,但常駐大小可能只有32 KB。

這是因爲操作系統在您實際使用它們時爲您的程序分配頁面(通常爲4 KB)。

例如它會在啓動時分配最大堆大小,但是在每個頁面被使用之前,您的程序不會佔用太多的主內存。

您可能很難爲JVM找到此信息,因爲這是OS提供的功能,所有程序都以此方式工作。即它不是JVM所特有的。