2009-07-14 68 views
0

我有一個applet,它需要更多或更少的內存,具體取決於客戶端有多少數據。-appm和獨立Java進程之間的Xmx區別

我們通常推薦使用Java 1.6最新版本,但實際上我們支持Java 1.5+,所以我們在小程序中提供了一個保護,它顯示一個對話框,提示「內存不足」並提示如何增加記憶。

但是,我真的很驚訝地發現-Xmx在小程序和獨立進程中的工作方式不同,而且我無法確定小程序是否具有足夠的內存。

這裏是它是如何做:

  • 小程序接收下列參數:
    • PARAM NAME = 「java_arguments」 值= 「 - Xmx153m」(當然這工作在Java 1.6的更新10,否則會得到64M用Java 1.5和Java 1.6之前更新10)
    • PARAM NAME = 「required.memory」 VALUE = 「153」
  • 在運行時,我們比較required.memory調用Runtime.getRuntime()。maxMemory()
  • 與153M的一個小程序,我們得到143589376的限制,但在一個獨立的應用程序,我們得到155516928
  • 153 * 1000 * 1000 = 1.53 (我沒有使用1024 1K,以防萬一),這絕對是超過143589376.

如果我使用0.9的係數,以避免任何近似的JVM似乎運作良好,但是這是正確的值 - 0.9?他們如何計算這個限制,爲什麼它在獨立的應用程序和小程序中有所不同?

回答

2

在Java內存上玩遊戲的時間。首先,Java內存不足(即實際獲得OutOfMemoryError)受到正在運行的GC的特性的影響。

與名稱暗示的相反,您可以獲得OutOfMemoryError而不會實際用完內存;它也會在運行時間決定其花費的時間量爲GC'ing(source,它埋在那裏)時拋出。

此外,您可以通過耗盡內存的特定來獲得OutOfMemoryError。請記住,Java GC是一個世代收藏家,如果你碰巧耗盡了其中一代人(我想說的是「終身」的一代,但我可能是錯的),那麼你的內存實際上已經不足。這意味着您可以在OS視圖中留下堆空間,但無法在Java堆上分配任何內容。

最後,還有一些與GC相關的實際開銷可能會佔用一些堆空間。


更重要的是可能你的情況要發生,是以下某種變型:你的代碼在兩個獨立和applet上下文中運行,每個上下文具有不同的安全管理和不同的啓動行爲;這意味着一組不同的類(涉及永久代)被涉及,具有不同的依賴關係。我猜測applet「stack」的厚度較大,因爲它們的行爲更具有明顯的約束,並且可能佔了maxMemory()中的大部分差異。

簡而言之,可用內存的差異可能是由於Java運行時爲自己的操作保留的內存發生了一些變化。這可能是與GC相關的,與安全策略相關的,或者只是針對Applet環境加載的不同類與獨立類加載的。在確定要返回的內容時,Runtime.maxMemory()也可能會考慮上述任何「內存不足」情況。因此,0.9值可能是一種實施副作用,可能會在未來發生變化。

0

Kevin的確,它與applet的運行方式和桌面應用程序之間的區別是有意義的,但令我感到震驚的是,applet和applet之間的最大(我認爲更大)內存有很大差異一個桌面應用程序,這是〜8%。如果它是如你所說的「小程序」堆棧「更厚,考慮到他們的行爲更嚴格的限制」我期待,小程序將獲得更大的最大內存,而不是獨立版。

我在applet和應用程序之間進行了一些測量。兩者都收到相同的參數(-Xmx128M),兩者都使用相同的JVM運行 - Java HotSpot™64位服務器VM版本11.3-b02(第一次我認爲小程序正在運行客戶端JVM並且桌面正在運行服務器JVM,但似乎都與服務器JVM)

當然,在現實中不同的參數收到的JVM,但沒有重大(我認爲):

  • 小程序:-D__jvm_launched = 426431678538 -Xbootclasspath/A :/usr/jvm/64/jdk1.6.0_13/jre/lib/deploy.jar:/usr/jvm/64/jdk1.6.0_13/jre/lib/javaws.jar:在/ usr/JVM/64/jdk1。 6.0_13/jre/lib/plugin.jar -Xmx128m
  • standalone:-Xrun jdwp:transport = dt_socket,address = 127.0.0.1:54876,suspend = y,server = n -Xmx128M -Dfile.encoding = UTF-8

Applet:max。內存= 119.314K

    • PS伊甸園空間:14,592K
    • PS生存空間:14.528K
    • PS老根:87.424K
      • 總:116.544K
  • 非堆
    • 紀念品普爾代碼高速緩存:49.152K
    • 紀念品普爾PS彼爾姆代:86.016K
      • 總數:135。168K

桌面:最大。內存= 129.302K

    • PS伊甸園空間:8.704K
    • PS生存空間:3.008K
    • PS老根:116.544K
      • 總:126.272K
  • 非堆
    • 紀念品普爾代碼高速緩存:49.152K
    • 紀念品普爾PS彼爾姆代:65.536K
      • 總計:135.168K

的這兩個JVM之間差異很大

  • PS燙髮根,小應用程序有一個更大的塊 - 這是有道理的,因爲小程序將與單機版相比,裝載可能的其他類(但即使在這種情況下,「老根」要小得多,這是奇怪的,因爲通常都這些額外的課程,最終獲得了「老根」)
  • 堆內存,伊甸園/倖存者/老將軍applet的老根之間完全不同的比率是獨立的老根的75%,這是一個很大的區別,我會說,如果期待(最近的)相同的內存模型,我很友善,因爲當我將應用程序作爲applet或桌面應用程序運行時,應該沒有什麼區別。

現在我更糊塗了,不僅如此,我不知道如何計算max.memory比(0.9確實不能與未來的JVM版本有效),但我的應用程序能拿出來的記憶當作爲applet運行時。當它作爲一個applet運行以保證安全時,我需要增加大約10-15%的最大內存。

我仍然不爲什麼這樣的不同的堆比(在同一臺機器上)和一個較小的堆(特別是考慮到一個applet需要附加的類)信服。

任何原因?我現在很好奇,這超出了我的需要,以檢查applet是否擁有我認爲應該達到的最大內存量。

相關問題