启动时的jvm问题

时间:2010-05-11 12:30:35

标签: java memory jvm heap

我可以将最大内存设置为1000而不是更多,如果我将内存设置得多于此值,则会引发以下错误。

初始化VM时出错 无法为对象堆保留足够的空间 无法创建Java虚拟机。

我的问题是,为什么jvm会在启动时查找最大内存?

提前致谢。

5 个答案:

答案 0 :(得分:3)

Sun JVM需要一个连续的内存区域用于其堆。使用Sysinternals套件中的工具vmmap,您可以准确地检查Java进程的内存布局。为此,编写一个简单的Java程序,如下所示:

public class MemoryLayout {
    public static void main(String[] args) throws java.io.IOException {
        System.in.read();
    }
}

编译该程序并使用大堆设置

运行它
javac MemoryLayout.java
java -Xmx1000m -Xms1000m MemoryLayout

然后,启动vmmap,选择java进程并查找大小大于1000000k的黄色内存区域。这是JVM堆。再看下面,你最终会找到一个紫色的行,表明有一个DLL文件被映射。此DLL文件可以防止JVM堆变大。

如果您知道自己在做什么,则可以 rebase 该DLL,因此它将被加载到不同的地址。 Microsoft提供了一个名为rebase.exe的工具,作为 Microsoft Platform SDK 的一部分(我的版本为5.2.3790.1830)。

答案 1 :(得分:2)

有两个命令行参数直接控制(普通)堆的大小:

  • -Xmx<nnn>设置最大堆大小
  • -Xms<nnn>设置初始堆大小

在这两种情况下,<nnn>都是一个字节数,末尾有km,分别表示千字节和兆字节。初始大小给出了JVM启动时分配的堆大小,最大大小限制了它可以增长的大小。 (但是除了正常的堆之外,JVM还为缓冲区,“permgen”堆,堆栈和其他东西分配内存。)

目前尚不清楚您实际提供的选项。 (值1000没有任何意义。-Xmx大小必须大于2兆字节且-Xms大小必须大于1兆字节;请参阅{{3 }}。)

使初始堆大小小于最大堆大小有利有弊;例如-Xms100m -Xmx1000m。但是没有要点使最大堆大小大于机器可以分配给JVM的虚拟内存量。

答案 2 :(得分:1)

  

为什么jvm会在启动时查找最大内存。

它希望确保它最终可以分配您可能拥有的最大金额。

为什么你需要设置一个比机器实际支持的更高的最大值?

答案:如果您可以将其设置为基本无限制,这将使JVM配置更容易,特别是如果您部署到不同的计算机上。这在早期版本中是可行的,但对于当前的Sun JVM,您必须为每台机器找出“适当的”值。希望将来会有更多聪明/自动的内存设置。

答案 3 :(得分:1)

由于实现原因详细阐述here(基本上它使性能更快并且这是它们的优先级)JVM需要连续的内存寻址,因此必须确定它在启动时具有该内容,否则它可能是可用的后面。

事实上,JVM在很多方面都是面向服务器端的技术。这就是Java受欢迎的地方,因此引起了开发人员的注意。

答案 4 :(得分:0)

如果在64位操作系统上使用64位JVM,则不会出现此问题。这只是32位操作系统的问题。