Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 针对高响应服务器应用程序优化JVM(GC)_Java_Performance_Jvm_Garbage Collection - Fatal编程技术网

Java 针对高响应服务器应用程序优化JVM(GC)

Java 针对高响应服务器应用程序优化JVM(GC),java,performance,jvm,garbage-collection,Java,Performance,Jvm,Garbage Collection,我在64位Linux上运行应用程序服务器,有8个核心CPU和6 GB内存 服务器必须具有高度响应能力 经过一些检查,我发现服务器上运行的应用程序创建了大量短期对象,并且只有大约200~400 MB的长期对象(只要没有内存泄漏) 读后 我使用这些JVM选项 -server -Xms2g -Xmx2g -XX:MaxPermSize=256m -XX:NewRatio=1 -XX:+UseConcMarkSweepGC 结果:小GC需要0.01~0.02秒,大GC需要1~3秒 小GC经常发生 如何

我在64位Linux上运行应用程序服务器,有8个核心CPU和6 GB内存

服务器必须具有高度响应能力

经过一些检查,我发现服务器上运行的应用程序创建了大量短期对象,并且只有大约200~400 MB的长期对象(只要没有内存泄漏)

读后 我使用这些JVM选项

-server -Xms2g -Xmx2g -XX:MaxPermSize=256m -XX:NewRatio=1 -XX:+UseConcMarkSweepGC
结果:小GC需要0.01~0.02秒,大GC需要1~3秒 小GC经常发生

如何进一步改进或调优JVM

更大的堆大小?但是GC需要更多的时间吗

较大的新闻大小和最大新闻大小(针对年轻一代)

其他收藏家?并行GC


让主要GC更频繁地发生是一个好主意吗?怎么做呢?

您可能有兴趣尝试低暂停,而不是同时进行标记扫描(虽然它不一定对所有集合都更有效,但应该有更好的最坏情况)。它是由
-XX:+UseG1GC
启用的,应该是非常棒的酱汁,但是在生产中使用它之前,您可能需要对它进行彻底的评估。从那以后,情况可能有所改善,但一年前似乎有点问题,如图所示

结果:小GC持续时间为0.01~0.02秒,大GC持续时间为1~3秒,小GC持续发生

除非您报告暂停,否则我会说CMS收集器正在执行您要求它执行的操作。根据定义,CMS将使用比串行和并行采集器更大比例的CPU。这是您为低暂停时间支付的罚款


如果您看到1到3秒的暂停时间,我认为您需要进行一些调整。我不是专家,但看起来您应该先将
cmSinitiatingOccinecyFraction
的值从默认值92降低


增加堆大小将提高GC的“吞吐量”。但是,如果您的问题是长暂停,则增加堆大小可能会使问题变得更糟。

如果您有足够的cpu,垃圾收集与程序并行运行是完全可以的,您可以这样做

您想要的是绝对确保不会遇到垃圾收集暂停主程序的情况


您是否尝试过简单地不声明任何标志,只声明您想要服务器VM(对于Sun JVM),然后将服务器置于重载状态以查看其行为?只有到那时,你才能看到,如果你通过修补选项得到了任何改进。

这实际上听起来像一个吞吐量应用程序,应该使用吞吐量收集器。我会平衡新一代的大小,使其足够大,以避免GC太频繁,并足够小,以防止长时间暂停。对我来说,20毫秒听起来像是一个很长的小调GC。我还怀疑你的幸存者空间设置得太大,只是被浪费了。如果你没有太多的生存到老一代,你不应该有那么多的生存到你的小地面军事


最后,您应该使用jvmstat和VisualGC来真正了解应用程序是如何使用内存的。

小心。。。。如果你不谨慎,GC可能是一个棘手的问题。在任何运行时(JVM for Java/CLR for.Net)中都会发生几个进程。一般来说,内存的早期优化(年轻一代垃圾收集/Young Gen GC和老一代垃圾收集/Old Gen GC)。年轻一代gc经常发生,通常归因于你较小的停顿/打嗝。老一代gc通常是当你看到“停止世界”的长时间停顿时发生的事情

你为什么会问?运行时/JVM出现暂停的原因是,当运行时清理堆时,它必须经历所谓的相变。它会停止运行应用程序的线程,以便标记和交换指针以优化可用内存。Yong gen的速度更快,因为它主要释放只是暂时的对象。然而,Old gen会计算堆上的所有对象,当内存耗尽时,它会启动以释放急需的内存

为什么要谨慎?使用的堆越多,旧gen在暂停时间内的性能就越差。堆的总大小为2-4GB,在Java6(JDK1.6+)等现代运行时上应该可以。一旦你超过这个阈值,你就会看到暂停时间呈指数级增长。我遇到过一些必须重新启动服务器的客户机,比如在一些罕见的情况下,堆很大,GC暂停时间可能比完全重新启动要长

有一些新的工具非常酷,可以让你在评估GC是否是你的痛苦时处于领先地位。JHiccup就是其中之一,它在网站上是免费的。但现在我认为它只适用于Linux。他们还有一个JVM,它有一个重新构建的GC算法,可以运行无暂停。。。但如果您使用非关键应用程序部署在单服务器上,则可能不具有成本效益(该应用程序不是免费的)

总之,如果您的运行时/JVM/CLR堆小于2GB,添加更多内存将有所帮助。一定要给自己一些开销。如果可能,您永远不希望达到100%的堆大小/内存大小。也就是说,长时间的停顿是最长的。给自己一个20%以上的额外记忆,超过你认为你需要的。这样,您就有了GC算法移动对象进行优化的空间。如果你曾经打算做一个大人物。。。有一个工具修复了大约1990年的JVM技术(Azul Systems Zing JVM),但它不是免费的。他们确实提供了一个开源工具来诊断GC问题。JVM(正如我所尝试的那样)还有一个非常酷的线程级可见性工具,可以让您报告生产中的任何泄漏、错误或锁定,而不需要额外的开销(一些卸载JVM已经处理的数据和时间戳的技巧)。这节省了大量的开发人员测试时间。。。但是,n
java -verbose:gc myProgram
java -Xloggc:D:/log/myLogFile.log -XX:+PrintGCDetails myProgram