1

我们为 CF9 服务器设置了 JVM,以分配最大 2GB 的堆空间。通常,它只分配大约 750MB 到 1GB,而我们实际上只使用了大约 500MB。

一个流氓脚本刚刚被触发,它最终占用了堆空间,因此 JVM 分配了完整的 2GB 限制。现在,我们回到了正常速度,只使用了分配的 2GB 中的 500MB,我们的服务器现在的内存使用率为 90%。

当 JVM 不再需要分配那么多空间时,我们是否可以使用任何设置来缩小 JVM 的最大堆空间?或者,这会一直保持这种状态,直到下次重新启动?只是想知道,因为我们在服务器上只剩下 10% 的内存用于“摆动”空间......

谢谢!

编辑:

只是为了澄清一点。我们通过设置 JVM 参数“-Xms750m”将初始堆大小设置为 750MB。我们的最大堆大小由 JVM 参数“-Xmx2048M”设置。在脚本运行之前,我们分配的堆大小约为 1GB。在这 1GB 中,我们平均只使用了 500MB。脚本运行后,堆被推到了极限,所以现在有 2GB 的预分配堆空间,我们再次平均只使用了 500MB。

因此,这使 Windows 记录了 90% 或更多的内存使用情况。JVM 可能至少可以释放GB 或更多,因为它从未使用过,但是,我们不知道如何强制这种情况发生,或者是否有某种 JVM 设置来执行此操作自动地。

4

2 回答 2

1

您可以运行完整的 GC,它会缩小堆。至少 750 兆的操作系统可以“回收”该内存(你真的不需要做任何事情)。但是,如果您的内存受限,那么您将来可能会遇到争用问题,因此您可能会考虑进行更好的调整。我通常将最小值和最大值设置为相同,这样我就不必仔细考虑这个问题。无论如何 - 这是一个可以帮助你的脚本:

<Cfset runtime = CreateObject("java","java.lang.Runtime").getRuntime()>

<cfset fm = runtime.freememory()/>

<Cfset fm = int((fm/1024)/1024)/>

<cfset usedmem = 1270-fm/>
<cfoutput><br>
<br>
Free: #fm# megs<br>
Used: #usedmem# megs<br>
</cfoutput>

<cfset obj = createObject("java","java.lang.System")/>

    <cfset obj.gc()/>

    <cfset obj.runFinalization()/>

脚本的第一部分显示可用内存,第二部分运行完整的垃圾收集(也完全暂停,因此根据您的流量和硬件,这可能会很明显)。

祝你好运 :)

于 2012-07-18T16:20:16.673 回答
0

如果堆再次返回到 500 meg 的报告,那么有几种可能发生的情况:

内存用于 PermGen。垃圾收集器不会以同样的方式(如果有的话)清除 Perm。如果您可以从服务器上的 JDK 运行 JPS 或 JVisualVM,那么您可以了解内存的使用位置,因为它们会报告 Perm Gen 的使用情况。

另一种可能性是您使用的操作系统度量反映了进程使用的最大内存,而不是当前内存。我不是这里的专家,但如果您可以准确发布您使用哪些指标来显示内存使用情况,这可能会很有用。

我想JVM可能不会释放内存,它是垃圾收集回操作系统,尽管我自己没有看到这种情况发生。

当您的流氓脚本运行时,您说它在崩溃之前占用了整个堆。它是否因 OutOfMemoryException 而死?如果您扫描异常日志,是否有任何关于哪些线程崩溃的信息?通常,一旦您的 JVM 经历了 OOM,您可能应该重新启动,因为您无法判断任何应用程序状态是否已损坏。

于 2012-07-18T16:19:31.680 回答