java最大堆大小,多less太多了

我遇到了在tomcat中运行的JRuby(rails)应用程序的问题。 有时页面请求可能需要一分钟才能返回(即使rails日志在几秒钟内处理了请求,所以显然是一个tomcat问题)。

我想知道什么设置是最佳的Java堆大小。 我知道没有明确的答案,但我想也许有人可以评论我的设置。

我在一个有1.7克RAM的小型EC2实例上。 我有以下的JAVA_OPTS:

-Xmx1536m -Xms256m -XX:MaxPermSize=256m -XX:+CMSClassUnloadingEnabled 

我首先想到的是Xmx太高了。 如果我只有1.7GB的,我分配1.5GB的Java,我觉得我会得到很多的传呼。 通常我的java进程显示(顶部)1.1克res内存和2g虚拟。

我也读过一些地方 ,将Xms和Xmx设置为相同的大小将有助于消除内存分配的时间花费。

我不是一个Java人,但我一直负责解决这个问题,我试图找出从哪里开始。 任何提示都非常感谢!

更新
我已经开始使用-XX:+PrintGCDetails分析垃圾收集转储

当我注意到这些偶尔很长的加载时间,gc日志坚果。 我做的最后一个(花了25s完成)我有gc日志行,例如:

 1720.267: [GC 1720.267: [DefNew: 27712K->16K(31104K), 0.0068020 secs] 281792K->254096K(444112K), 0.0069440 secs] 1720.294: [GC 1720.294: [DefNew: 27728K->0K(31104K), 0.0343340 secs] 281808K->254080K(444112K), 0.0344910 secs] 

其中约300个单一的请求! 现在,我不完全明白,为什么总是从28m降到0。

虽然我还没有在Tomcat上运行任何JRuby应用程序,但是我已经在各种J2EE应用程序服务器上运行了ColdFusion应用程序,而且我也遇到了类似的问题。

在这些常见问题解答中 ,您会看到SOracle表示,在32位Windows上,您将被限制为1.4到1.6 GB的最大堆大小。 我从来没有得到它稳定的高,我怀疑你正在运行一个类似的configuration。

我的猜测是,你的请求花费很长时间来运行一个堆大小很高的B / C,JVM已经分配了比Windows必须提供的更多的物理内存,于是Windows花费了大量的时间换页内存到磁盘,因此它可以向JVM提供所需的内存量。

我的build议,虽然违反直觉,但实际上你将最大堆大小降低到1.2GB左右。 如果您发现应用程序的请求处理速度有所下降,您也可以提高最小大小,而JVM必须向Windows请求更多的内存,以便在填充未收集的对象时增加堆的大小。

你的问题的一部分是,你可能会饿死所有其他进程的内存。 对于-Xms-Xmx我的一般经验法则如下:

-Xms : <System_Memory>*.5
-Xmx : <System_Memeory>*.75

所以在一个4GB的系统上,它会是: -Xms2048m -Xmx3072m ,在你的情况下,我会去-Xms896m -Xmx1344

除了以前的答案之外,还应该考虑到PermGen。 PermGen不是堆空间的一部分。 与您目前的configuration您的Java进程可以总结到1792mb这是您的机器的总量。

我知道已经有一个答案select了,但是,这里是我的解释。

首先,在您使用的命令行中,您已经为Java堆(-Xmx1536m)预留了1536兆字节,为PermGen预留了256 MB(-XX:MaxPermSize = 256m)。 PermGen与Java堆分开分配,用于存储JVM中加载的Java类。

这两个区域已经加起来共计1792兆字节的RAM。

但除此之外,还需要加载JVM本身(JVM的本机代码)和RAM以存储由JIT编译器生成的代码的RAM。

我怀疑所有这些加起来,你提到的2千兆字节的虚拟。

最后,你还必须考虑到服务器上运行的其他东西,也需要RAM。 你没有真正提到在服务器上使用了多less交换。 这会告诉你机器是否交换,导致应用程序反应缓慢。 您应始终防止JVM触及交换。 经常触发垃圾收集器要比分配太多的堆并将Java堆的一部分换出来好得多。