最近我得到了一个 VPS 服务器并且正在运行 Coldfusion,网站运行良好,直到它的流量越来越多,我开始遇到“OutOfMemory”异常。
我曾想过简单地增加VPS服务器的内存,但是这并没有帮助。
在谷歌上搜索后,我在 CF Admin 设置中找到了一个设置,用于设置 JVM 堆内存。它符合标准:最大堆大小为 512MB,最小堆大小为空。经过一番尝试,我现在将其设置为最小 50MB,最大 200MB,好消息是,我不再收到“OutOfMemory”异常。到目前为止一切顺利!
但当网站上有大约 50 个活跃访问者时,网站就开始变慢了。CPU 使用率只有 8% 左右(Windows 任务管理器),任务管理器也显示 3GB RAM 的使用率只有 30% 左右。
因此,我认为可以调整我的值以使用更多 RAM。老实说,我不了解这些 JVM 内存堆设置,所以我不知道什么设置对我来说比较好。
我找到了一个显示内存使用情况的CF脚本,详细信息如下:
Heap Memory Usage - Committed 194 MB
Heap Memory Usage - Initial 50.0 MB
Heap Memory Usage - Max 194 MB
Heap Memory Usage - Used 163 MB
JVM - Free Memory 31.2 MB
JVM - Max Memory 194 MB
JVM - Total Memory 194 MB
JVM - Used Memory 163 MB
Memory Pool - Code Cache - Used 13.0 MB
Memory Pool - PS Eden Space - Used 6.75 MB
Memory Pool - PS Old Gen - Used 155 MB
Memory Pool - PS Perm Gen - Used 64.2 MB
Memory Pool - PS Survivor Space - Used 1.07 MB
Non-Heap Memory Usage - Committed 77.4 MB
Non-Heap Memory Usage - Initial 18.3 MB
Non-Heap Memory Usage - Max 240 MB
Non-Heap Memory Usage - Used 77.2 MB
Free Allocated Memory: 30mb
Total Memory Allocated: 194mb
Max Memory Available to JVM: 194mb
% of Free Allocated Memory: 16%
% of Available Memory Allocated: 100%
我的 JVM 参数是:
-server -Dsun.io.useCanonCaches=false -XX:MaxPermSize=192m -XX:+UseParallelGC - Dcoldfusion.rootDir={application.home}/../ -Dcoldfusion.libPath={application.home}/../lib
我可以给 JVM 更多的内存吗?如果可以,我应该使用什么设置?
非常感谢!!
答案1
关于 GC 和性能的一个很好的参考资料是 Oracle 的 GC Tuning
http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html
一般来说,分配给 JVM 的内存越多越好。年轻代设置得越大(大约是 VM 总大小的一半)越好。我玩过大小高达 28 GB 的 JVM。
对于监控,您需要使用 jconsole(如果您是系统管理员,它的界面、仪表和限制都很糟糕,但这就是您所拥有的),并特别观察您的 GC 活动和总扫描次数。这也会让您了解您的内存使用模式是什么样的。这是一个用 Java 仪表化的 GUI 监视器。您需要在 JVM 中启用 JMX 扩展才能使用它。
要查看实际使用内存的内容,可以使用“jmap”实用程序显示堆大小(“jmap -heap”)和堆中对象的清单(“直方图”)(“jmap -F -histo”)。前者通常运行很快,我见过后者运行 20-30 分钟,在此期间 JVM 对其他任务没有响应,因此在生产实例上不能轻易使用此实用程序。
有点违反直觉的是,更大您创建 ParNew / 年轻代,GC 运行的频率就越低、速度就越快、效率就越高。GC 通过跟踪堆中的活动对象来工作,并在 ParNew 填满时运行。ParNew 越大,时间就越长,过期(死亡)的对象就越多,因此 GC 运行的频率就越低,死亡的对象就越多。这样就可以使用更多的内存进行 GC。我们的配置中 ParNew 被设置得非常小(约 50 MB 左右),将其增加到 1-2 GB 后,GC 开销就下降到以前的 1-5% 左右(现在的 CPU 开销为 0.01% - 2%,具体取决于主机/工作负载,而以前是 10-50%)。
您还需要调整 PermGen 的大小,以免空间不足。PermGen 是保存持久对象(主要是类)的地方,空间不足通常是一件坏事。
答案2
答案当然是“取决于”你的应用程序。第一步是监控你的内存使用情况。有很多产品可以提供帮助:SeeFusion、Fusion Reactor……以及标准 JVM 监控,如 jconsole 和 VisualVM。
找出您当前的堆使用情况,并将其提高,直到 GC 变得更加稳定。还要确保您的 PermGen 空间足够大(如果您使用框架或大量对象,这可能是一个问题。)
实际上,当我们的应用程序还没有接近
答案3
由于需要更频繁地进行垃圾收集以保持堆较小,因此系统可能在更高负载下开始变慢。
最大堆大小实际上限制了 JVM 的最大内存消耗量;如果您想让它拥有更多的系统 RAM,则需要增加最大堆大小。
但是,如果软件占用了那么多内存,需要那么多垃圾收集,那么使用更大的堆大小可能只能延迟不可避免的崩溃。尝试更高的设置(从 1024 MB 开始,然后增加到 2048 MB),但如果这只能延迟崩溃,那么您需要优化应用程序代码,使其在 RAM 使用方面更加温和。
答案4
Kai 整理了有关 JVM 调优的大量信息。最小 50 和最大 200 相当低。我建议(在 32 位上)尝试将最大值和最小值都设为 1024,然后看看效果如何。