-Xmx属性和可用的系统内存关联

时间:2012-08-10 17:04:34

标签: java memory memory-management memory-leaks garbage-collection

我心中有一个问题。假设我有两个参数传递给JVM: -Xms256mb -Xmx1024mb 在程序开始时分配256MB。接下来,创建一些对象,JVM进程尝试分配更多内存。假设JVM需要分配800MB。 Xmx属性允许,但系统上当前可用的内存(比如说Linux / Windows)是600MB。是否可能抛出OutOfMemoryError?或者交换机制可能会发挥作用?

我的第二个问题与GC算法的质量有关。假设我有jdk1.5u7和jdk1.5u22。是否有可能在后一个JVM中内存泄漏消失并且OutOfMemoryError不会发生? GC的质量能否在最新版本中更好?

4 个答案:

答案 0 :(得分:2)

GC的质量(除非有错误的GC)不会影响内存泄漏,因为内存泄漏是应用程序的工件 - GC无法收集非实际垃圾。

如果JVM需要更多内存,它将从系统中获取。如果系统可以交换,它将交换(像任何其他进程一样)。如果系统无法交换,您的JVM将因系统错误而失败,而不是OOM异常,因为系统无法满足请求,而且这一点实际上是致命的。

通常,您永远不希望部分换出活动JVM。当系统通过虚拟内存系统使循环页面崩溃时,GC事件将粉碎你。将一个空闲的后台JVM作为一个整体进行交换是一回事,但是如果你加载1G的RAM并且你的主进程需要1.5GB,那么你就遇到了一个重大问题。

JVM就像呼吸的空间。当他们没有足够的内存时,我已经看到JVM处于GC死亡螺旋中,即使他们没有内存泄漏。他们根本没有足够的工作集。添加另一块堆将JVM从可怕的锯齿GC图转换为快乐的锯齿图。

为JVM提供所需的内存,您和它将会更加快乐。

答案 1 :(得分:2)

“记忆”和“RAM”不是一回事。内存包括虚拟内存(交换),因此您可以在获得OutOfMemoryError之前分配总共空闲RAM +免费交换。

答案 2 :(得分:0)

分配取决于使用的操作系统。 如果你分配了太多的内存,也许你可能最终将部分加载到交换中,这很慢。 如果您的程序运行速度较慢取决于VM如何处理内存。

我不会指定一个不那么大的堆,以确保它不会占用所有内存来防止VM的速度变慢。

答案 3 :(得分:-1)

关于你的第一个问题:
实际上,如果机器无法分配您要求的最大堆大小的1024 MB,它甚至不会启动JVM。
我知道这是因为我注意到它经常尝试打开具有大堆大小的eclipse,并且操作系统无法分配JVM无法加载的较大堆空间。您也可以自己尝试确认。所以其余的细节与你无关。如果你的程序使用太多交换(与所有语言相同),那么表现将是可怕的。

关于你的第二个问题:

  

内存泄漏消失

不可能,因为它们是必须修复

  

和OutOfMemoryError没有发生? GC的质量可以更好吗?   在最新版本?

这可能发生,例如,如果使用GC中的某些不同算法,并且它在您看到异常之前设法启动。但是,如果你有内存泄漏,那么很可能会掩盖它,或者你会发现它是间歇性的 此外,各种JVM都可以配置不同的GC

<强>更新
我必须承认(在看到@Orochi注释后)我注意到Windows上最大堆上的行为。我不能肯定这也适用于linux。但你可以自己尝试一下。

更新2: 作为@DennisCheung评论的答案 来自IBM(我的重点):

  
    

该表显示了可能的最大Java堆和最大Java堆大小设置的建议限制......拥有比所有需要的物理内存更多的物理内存是很重要的。机器上的进程组合在一起以防止分页或交换。分页会降低系统性能并影响Java内存管理系统的性能。