2008-09-19 27 views
5

我們有一個需要大量堆空間的java程序 - 我們用(其中包括命令行參數)參數-Xmx1500m啓動它,它指定最大堆空間1500 MB。在剛剛重新啓動的Windows XP盒子上啓動該程序時,它將啓動並運行,沒有問題。但是,如果該程序已運行了好幾次,計算機已經運行了一段時間,等等,當它試圖啓動我得到這個錯誤:查看/解決Windows XP內存碎片的工具

 
Error occurred during initialization of VM 
Could not reserve enough space for object heap 
Could not create the Java virtual machine. 

我懷疑Windows本身是由內存碎片的痛苦,但我不知道如何證實這種懷疑。在發生這種情況時,任務管理器和sysinternals procexp報告2000MB空閒內存。我曾看過this question related to internal fragmentation

所以第一個問題是,如何確認我的懷疑? 第二個問題是,如果我的懷疑是正確的,是否有人知道任何工具來解決這個問題?我環顧四周,但除了定期重啓機器,我還沒有發現任何有用的東西。

ps - 更改操作系統目前也不是可行的選擇。

回答

2

與Torlack一致,這很大程度上是因爲其他DLL正在被加載並進入某些位置,從而在一個大塊中分割虛擬機的內存量。

你可以在WinXP一些工作,如果你有超過3G的內存多拿一些窗戶的東西搬來搬去,在這裏查找PAE: http://www.microsoft.com/whdc/system/platform/server/PAE/PAEdrv.mspx

你最好的選擇,如果你真的需要超過1.2G內存爲您的Java應用程序,是看在64位窗口或Linux或OSX。如果你在你的應用中使用任何類型的本地庫,你將不得不重新編譯它們爲64位,但它會比試圖重新設計DLL和東西來最大限度地提高你在32位窗口中獲得的內存要容易得多。

另一種選擇是將程序分成多個虛擬機,並讓它們通過RMI或消息傳遞等方式與彼此通信。這樣每個虛擬機可以擁有你需要的內存的一部分。不知道你的應用程序做什麼,我不知道這將有助於以任何方式,雖然...

0

對該應用程序使用Minimem(http://minimem.kerkia.net/)可能會解決您的問題。不過,我不確定這是你正在尋找的答案。我希望它有幫助。

0

也許你應該考慮啓動程序並預留內存,而不是在每次運行後終止虛擬機。尋找不同的GC選項並釋放你的對象。

2

除非您的頁面文件空間不足,否則此問題不是計算機內存不足。虛擬內存的全部重點是允許進程使用比物理上可用的更多的虛擬內存。

不知道JVM如何處理堆,這是一個有點很難說的到底是什麼問題,但常見的問題之一是,有沒有足夠的可用的連續可用地址空間的過程中,使堆被延伸。爲什麼在機器運行一段時間後這會成爲一個問題,這有點令人困惑。

我一直在研究類似的問題。我發現使用WinDBG運行程序並使用「!address」和「!address -summary」命令在追蹤進程虛擬地址空間碎片化的原因方面具有無可估量的價值。您也可以嘗試重新啓動後運行程序,並使用「!address」命令拍攝地址空間的圖片,然後在程序不再運行時執行相同操作。這可能會幫助你解決問題。也許簡單的一個額外的DLL加載可能會導致問題。

2

我懷疑問題是Windows內存碎片。 StackOverflow的另一個問題叫做Java Maximum Memory on Windows XP,它提到使用Process Explorer來查看DLL映射到內存的位置,然後通過重新綁定DLL來解決問題,以便以更緊湊的方式加載到內存中。

0

使用來自微軟SysInternals工具的vmmap來查看虛擬地址空間的碎片,並確定是什麼破壞了空間