-applet和独立Java进程之间的Xmx差异

-applet和独立Java进程之间的Xmx差异,java,memory,settings,Java,Memory,Settings,我有一个小程序,它需要多少内存取决于客户端有多少数据 我们通常建议使用Java 1.6最新版本,但实际上我们支持Java 1.5+,因此小程序中有一个保护,显示一个对话框,警告“内存不足”,并说明如何增加内存 然而,我非常惊讶地看到-Xmx在applet和独立进程中的工作方式不同,我无法确定applet是否有足够的内存 这是如何做到的: 小程序接收以下参数: param name=“java_arguments”value=“-Xmx153m”(当然这在Java1.6更新10中有效,否则在J

我有一个小程序,它需要多少内存取决于客户端有多少数据

我们通常建议使用Java 1.6最新版本,但实际上我们支持Java 1.5+,因此小程序中有一个保护,显示一个对话框,警告“内存不足”,并说明如何增加内存

然而,我非常惊讶地看到-Xmx在applet和独立进程中的工作方式不同,我无法确定applet是否有足够的内存

这是如何做到的:

  • 小程序接收以下参数:
    • param name=“java_arguments”value=“-Xmx153m”(当然这在Java1.6更新10中有效,否则在Java1.5和Java1.6更新10之前它将获得64M)
    • param name=“required.memory”value=“153”
  • 在运行时,我们将required.memoryruntime.getRuntime().maxMemory()进行比较
  • 小程序的限制为153M时,我们得到143589376,但在独立应用程序中,我们得到155516928
  • 153*1000*1000=153000000(我不是用1024表示1K,只是以防万一),这肯定超过143589376

如果我使用因子0.9来避免JVM中的任何近似值,似乎效果很好,但这是正确的值-0.9吗?他们是如何计算这个限制的?为什么在独立的应用程序和小程序中会有所不同?

是时候在Java内存上进行spiel了

首先,Java中的内存不足(即实际获取an)受到正在运行的GC特性的影响

与名称所暗示的相反,您可以得到一个OutOfMemoryError,而不会实际耗尽内存;当运行时决定它花费的GC'ing时间不多时(它埋在那里),也会抛出它

此外,您可以通过耗尽特定类型的内存来获得OutOfMemoryError。请记住,JavaGC是一个分代的收集器,如果您碰巧耗尽了其中一代(我想说的是“终身”的一代,但我可能错了),那么实际上您的内存也不足。这意味着您可以在OS视图中保留堆空间,但不能在Java堆上分配任何内容

最后,与GC相关的一些实际开销可能会占用一些堆空间


在您的情况下,更可能发生的是以下情况的一些变体:您的代码在独立和applet上下文中运行,每个上下文都有不同的安全管理器和不同的启动行为;这意味着涉及到一组不同的类(它们被放入到永久生成中),具有不同的依赖关系。我猜小程序“堆栈”越厚,因为它们的行为约束越严格,这可能是maxMemory()中的大部分差异的原因


简而言之,可用内存的差异可能是由于Java运行时为自己的操作保留的内存发生了一些变化。这可能与GC相关、与安全策略相关,也可能只是小程序环境与独立环境加载的不同类。在决定返回什么时,Runtime.maxMemory()还可以考虑上述任何“内存不足”条件。因此,0.9值可能是实现的副作用,将来可能会发生变化。

Kevin,小程序的运行方式与桌面应用程序的运行方式之间确实存在差异,但让我印象深刻的是,最大值存在很大差异(我认为更大)小程序和桌面应用程序之间的可用内存约为8%。如果如您所说,“小程序”堆栈“由于其行为受到更严格的限制而更厚”,我希望小程序将获得更大的最大内存,而不是独立版本

我在applet和应用程序之间进行了一些测量。两者都接收到相同的参数(-Xmx128M),都使用相同的JVM运行- Java HotSpot(TM)64位服务器虚拟机版本11.3-b02(我第一次认为小程序是用客户端JVM运行的,桌面是用服务器JVM运行的,但似乎两者都是用服务器JVM运行的)

当然,JVM实际上收到了不同的参数,但没有什么重要的(我认为):

  • applet:-D_ujvm_launted=426431678538-Xbootclasspath/a:/usr/jvm/64/jdk1.6.0_13/jre/lib/deploy.jar:/usr/jvm/64/jdk1.6.0_13/jre/lib/plugin.jar-Xmx128m
  • 独立:-Xrunjdwp:transport=dt_套接字,地址=127.0.0.1:54876,挂起=y,服务器=n-Xmx128M-Dfile.encoding=UTF-8
小程序:最大内存=119.314K

    • PS伊甸园空间:14592K
    • PS幸存者空间:14.528K
    • PS旧发电机:87.424K
      • 总数:116.544K
  • 非堆
    • 内存池代码缓存:49.152K
    • 内存池PS Perm Gen:86.016K
      • 总计:135.168K
桌面:最大内存=129.302K

    • PS伊甸园空间:8.704K
    • PS幸存者空间:3.008K
    • PS旧发电机:116.544K
      • 总数:126.272K
  • 非堆
    • 内存池代码缓存:49.152K
    • 内存池PS Perm Gen:65.536K
      • 总计:135.168K
这两个JVM之间的巨大差异

  • PS Perm Gen,applet得到了更大的块-这是有意义的,因为applet与独立版本相比可能会加载额外的类(但即使在这种情况下,“Old Gen”也要小得多,这很奇怪,因为通常所有这些额外的类最终都会进入“Old Gen”)
  • 堆内存,Eden/Survivor/Old Gen之间的比率完全不同。Applet的Old Gen是单机版Old Gen的75%,这是一个很大的区别,我会说,我很期待(olmost)