为JVM开始内存分配

3
我开始使用-Xmx选项来让我的进程使用更多的内存(256Mb,尽管我认为我目前使用的少于128Mb)。我也注意到了启动内存的-Xms选项,默认值为2Mb。我应该将这个值设置为什么,为什么?

参考:Java


2
我承认我太懒了,不想去查看(http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp),但是对于这样的问题,我的一般经验法则是:如果我不知道选项有什么用处,而且没有出现任何故障,我会将其保持原样,相信设置默认值的人的好判断。 - Carl Smotricz
4个回答

9
-Xmx参数定义了JVM堆的最大内存大小。您必须了解程序的性能并根据其负载情况设置此参数。如果将值设置过低,则可能会导致OutOfMemoryException或者程序的堆内存接近最大堆大小时出现非常差的性能。如果您的程序在专用服务器上运行,可以将此参数设置得更高,因为它不会影响其他程序。 -Xms参数设置了JVM的初始和最小堆内存大小。这意味着当您启动程序时,JVM会立即分配此数量的内存。如果您的程序从一开始就会消耗大量的堆内存,这将非常有用。这避免了JVM需要定期增加堆大小,因此您可以在那里获得一些性能提升。如果您不知道此参数是否会对您有所帮助,请不要使用它。
像Resin这样的服务器端Java应用程序的最佳实践是将最小的-Xms和最大的-Xmx堆大小设置为相同的值。您可以将其设置为256或512Mb。

1
我的做法是,当我发现需要出于某种原因提高mx时,我会使ms与之匹配,因为它正在达到该限制(否则您就不必提高mx)。我不确定这是否重要,但如果您知道您将需要它,为什么不一开始就分配所有资源呢?但是,如果您并非每次运行都需要高mx,则可以将ms保持较低。 - Bill K
@Bill 是的,现在的RAM就像是可以随意扔进机器里的东西。这种情况更多出现在应用程序需要与其他部分协调的时候。如果你有足够的RAM,你可以将其提前分配给Java。 - OscarRyz
我的想法是,在假设你需要内存并且必须使用你的-mx变量的情况下,那么就可以推断出你有内存来使用-ms,并且最终会需要它,那么在一开始设置它的负面在哪里呢? - Bill K
@Bill。早期的日子里,我们需要担心这个因素。 - gmhk

7

堆大小应该“适合”您的应用程序,但要找到正确大小并不容易。如果太小,您会耗尽内存,如果太大,则会浪费内存,并有冒长时间GC暂停的风险。当出现问题时(而且它们总是会出问题),拥有更多的堆可以更好地调试,并使任何泄漏的表现时间更长。

理想情况下,我会将-Xms设置为我认为我的应用程序需要运行的大小,将-Xmx设置为比此值大但不要太大的值。始终开启详细的垃圾收集并绘制正在使用的堆以检查已设置的值。

当我绘制堆时,我会查看正在发生的收集次数和类型。不要有太多收集,这很重要。然而,也不要拥有一个堆如此巨大,以至于几乎没有收集,因为它们发生时(完整gc不可避免),它们会受到伤害。理想情况下,希望获得一组定期间隔良好,暂停时间非常短的gcs。

话虽如此,对于32位Windows,-Xms应与-Xmx相同。这是因为Java(不考虑jrockit)需要连续的内存,而Windows的内存映射是分散的,因此尽早获得和锁定堆会更加划算。


2
Xmx是内存池的上限,而Xms是初始大小。这就是全部内容了。对于每个值的适当大小取决于应用程序的复杂性。将初始大小设置为大于2mb,主要优点就是JVM从操作系统请求更多内存的时间会更短。如果您将上限设置为256mb,则对于大多数企业应用程序来说,32mb-64mb的初始大小不算过高。
更多信息请参阅:http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html

1
这个值应该设置成多少,为什么?
当然取决于你的应用程序。
如果你知道你的应用程序在第一分钟最初消耗了64MB,那么使用默认值(2MB)将使VM请求内存多次,直到达到64MB。这些内存请求会稍微减慢你的应用程序,因为垃圾收集器可能会运行多次,尝试在VM请求更多内存之前释放空间。
如果你已经知道你将使用64MB作为起点,使用-Xms参数将让你预先分配那些内存。
如果你正在使用128MB并且有足够的可用内存,你可以使用java -Xms128m而不必担心长时间请求更多内存。
但是,这还取决于你的应用程序做什么,内存如何使用,何时需要等等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接