2009-07-14 21 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是否拥有我认为应该达到的最大内存量。

相关问题