我可以将最大内存设置为1000而不是更多,如果我将内存设置得多于此值,则会引发以下错误。
初始化VM时出错 无法为对象堆保留足够的空间 无法创建Java虚拟机。
我的问题是,为什么jvm会在启动时查找最大内存?
提前致谢。
答案 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>
都是一个字节数,末尾有k
或m
,分别表示千字节和兆字节。初始大小给出了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位操作系统的问题。