我有一个小程序需要更多或更少的内存,具体取决于客户端有多少数据。
我们通常建议使用Java 1.6最新版本,但我们实际上支持Java 1.5+,因此我们在applet中有一个保护,它显示一个对话框,其中包含“内存不足”的警告以及说明如何增加存储器中。
但是,我很惊讶地发现-Xmx在applet和独立进程中的工作方式不同,我实际上无法确定applet是否有足够的内存。
以下是如何完成的:
如果我使用因子0.9来避免JVM中的任何近似似乎运行良好,但这是正确的值 - 0.9?他们如何计算此限制以及为什么它在独立应用程序和applet中有所不同?
答案 0 :(得分:2)
Java内存的时间。
首先,Java中的内存不足(即实际获得OutOfMemoryError)受到正在运行的GC的特性的影响。
与名称所暗示的相反,您可以获得OutOfMemoryError而不会实际耗尽内存;它也会在运行时决定花费大量时间GC(source,它埋在那里)时抛出。
此外,您可以通过耗尽特定的种内存来获取OutOfMemoryError。请记住,Java GC是一代分类收集器,如果你碰巧耗尽了其中一代(我想说“终身”一代,但我可能错了)你也有效地失去记忆。这意味着您可以从操作系统视图中留下堆空间,但无法在Java堆上分配任何内容。
最后,有一些与GC相关的实际开销可能占用了一些堆空间。
在您的情况下更有可能发生的事情是以下的一些变体:您的代码在独立和applet上下文中运行,每个上下文都有不同的安全管理器和不同的启动行为;这意味着涉及一组不同的类(它们被敲入永久代),具有不同的依赖性。我认为applet“stack”更厚,因为它们的行为受到更严格的限制,这可能是maxMemory()中差异的主要原因。
简而言之,可用内存的差异可能是由于Java运行时为其自己的操作保留的内存的一些变化。这可能与GC相关,与安全策略相关,或者只是为Applet环境加载的不同类与独立类加载。在确定返回什么时,Runtime.maxMemory()也可以考虑上述任何“内存不足”条件。因此,0.9值可能是实施副作用,可能在将来发生变化。
答案 1 :(得分:0)
凯文,确实在applet的运行方式与桌面应用程序之间的区别是有意义的,但让我印象深刻的是,applet和a之间的最大内存(我认为更大)存在很大差异桌面应用程序,大约是8%。如果你说“applet”堆栈“由于对行为的更严格限制而更厚”我期待applet将获得更大的最大内存而不是独立版本
我在applet和应用程序之间进行了一些测量。两者都接收相同的参数(-Xmx128M),两者都使用相同的JVM运行 - Java HotSpot(TM)64位服务器VM版本11.3-b02(我第一次认为applet运行时客户端JVM和桌面运行时服务器JVM,但它似乎都与服务器JVM一起运行)
当然,JVM实际上收到了不同的参数,但没有什么重要的(我认为):
小程序:最大记忆= 119.314K
桌面:最多记忆= 129.302K
这两个JVM之间的巨大差异
现在我更加困惑,不仅仅是我不知道如何计算max.memory比率(事实上0.9对未来的JVM版本无效)但是我的应用程序在运行时可能会内存不足小程序。
,当它作为小程序运行时,我需要增加大约10-15%的最大内存。我仍然不相信为什么这样一个不同的堆比率(在同一台机器上)和一个较小的堆(特别是考虑到applet需要额外的类)。
有什么原因吗?我现在好奇,这超出了我需要检查applet是否具有我认为应该的最大内存量。