Windows上每个Java进程的最大内存量?

对于使用-Xmx的Java进程,可以在32位Windows上分配的最大堆大小是多少?

我问,因为我想在OpenMap中使用ETOPO1数据,原始二进制浮点文件大约是910 MB。

没有什么比回答你的问题的经验实验更好的了。 我编写了一个Java程序并在指定XMX标志的同时运行它(也使用XMS = XMX来强制JVM预先分配所有内存)。 为了进一步防止JVM优化,我主动分配X个10MB对象。 我在许多JVM上运行了一些测试,增加了XMX值,同时增加了分配的MB数量,在使用Sun和IBM JVM的不同32位操作系统上,这里是结果摘要:

操作系统:Windows XP SP2,JVM:Sun 1.6.0_02,最大堆大小:1470 MB
操作系统:Windows XP SP2,JVM:IBM 1.5,最大堆大小:1810 MB
操作系统:Windows Server 2003 SE,JVM:IBM 1.5,最大堆大小:1850 MB
操作系统:Linux 2.6,JVM:IBM 1.5,最大堆大小:2750 MB

这是详细的运行尝试以及分配类助手源代码:

WinXP SP2,SUN JVM:

 C:> java -version
 java版“1.6.0_02”
 Java(TM)SE运行时环境(版本1.6.0_02-b06)
 Java HotSpot(TM)客户端VM(版本1.6.0_02-b06,混合模式) 

java -Xms1470m -Xmx1470m Class1 142

即将创建对象141
对象141已创建

C:> java -Xms1480m -Xmx1480m Class1 145
VM初始化期间发生错误
无法为对象堆保留足够的空间
无法创建Java虚拟机。
WinXP SP2,IBM JVM

 
 C:> c:\ ibm \ jdk \ bin \ java.exe -version
 java版“1.5.0”
 Java(TM)2运行时环境,标准版(构建pwi32devifx-20070323(如果
 ix 117674:SR4 + 116644 + 114941 + 116110 + 114881))
 IBM J9 VM(build 2.3,J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223ifx-2007
 0323(已启用JIT)
 J9VM  -  20070322_12058_lHdSMR
 JIT  -  20070109_1805ifx3_r8
 GC  -  WASIFIX_2007)
 JCL  -  20070131 

c:\ ibm \ jdk \ bin \ java.exe -Xms1810m -Xmx1810m Class1 178

即将创建对象177
对象177创建

C:> c:\ ibm \ jdk \ bin \ java.exe -Xms1820m -Xmx1820m Class1 179
JVMJ9VM015W库j9gc23的初始化错误(2):无法实例化他
AP。 1820M要求
无法创建Java虚拟机。
Win2003 SE,IBM JVM

 C:>“C:\ IBM \ java”-Xms1850m -Xmx1850m Class1
睡了5秒钟。
完成。 

C:>“C:\ IBM \ java”-Xms1880m -Xmx1880m
1类
JVMJ9VM015W库j9gc23的初始化错误(2):无法实例化他
AP。 1880M要求
无法创建Java虚拟机。 Linux 2.6,IBM JVM

 [root @ myMachine~]#/ opt / ibm / java2-i386-50 / bin / java -version
 java版“1.5.0”
 Java(TM)2运行时环境,标准版(build pxi32dev-20060511(SR2))
 IBM J9 VM(build 2.3,J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20060504(已启用JIT)
 J9VM  -  20060501_06428_lHdSMR
 JIT  -  20060428_1800_r8
 GC  -  20060501_AA)
 JCL  -  20060511a 

/ opt / ibm / java2-i386-50 / bin / java -Xms2750m -Xmx2750m Class1 270

[root @ myMachine~]#/ opt / ibm / java2-i386-50 / bin / java -Xms2800m -Xmx2800m Class1 270
JVMJ9VM015W库j9gc23的初始化错误(2):无法实例化堆。 2800M要求
无法创建Java虚拟机。

这是代码:

 import java.util.StringTokenizer; public class Class1 { public Class1() {} private class BigObject { byte _myArr[]; public BigObject() { _myArr = new byte[10000000]; } } public static void main(String[] args) { (new Class1()).perform(Integer.parseInt(args[0])); } public void perform(int numOfObjects) { System.out.println("creating 10 MB arrays."); BigObject arr[] = new BigObject[numOfObjects]; for (int i=0;i  

对于大文件,我建议您使用内存映射文件。 这不使用堆空间(或非常少),因此在这种情况下,最大堆大小不应该是一个问题。

我们最近从Windows移植到Linux(因为VM大小问题)。

我听说过Windows VM大小(1200,1400,1600,1800)过去常常被抛出的数字。 在我们的Windows服务器(2003)上,在我们的环境中, 使用我们的应用程序 ,…我从未成功使用超过1280MB。 除此之外,我们的应用程序开始展示GC和OOM问题。

每当我得到一个新的VM版本时,我都尝试改变它的数量而且它永远不会改变。

你现在有一个900MB的文件,如果文件增加到1300MB怎么办? 你会怎么做?

你有很多选择

  1. 端口到Linux / Solaris。 这只需要硬件/软件,这通常是一个简单的移植练习。
  2. 使用64位Windows。 这可能不是没有GC问题 – 我听说过64位vms的不同故事。
  3. 重新设计应用程序以不同的方式处理文件,你能以某种方式逻辑地分割文件,你能以块的forms读取文件并以不同的方式处理它吗?

使用OpenMap的其他人一定遇到过这个问题。 你能利用他们的知识而不是重新发明任何轮子吗?

正如评论中提到的问题所述,存在实际限制,大约1200 MB。

但是,您描述的情况比内存大小更深入。

当您读取910 MB二进制数据并从中构建网络对象时(而不是仅将数据维护为字节数组),最终会消耗比910 MB更多的内存。 一个合理的估计是内存中表示将消耗两倍的内存 – 这是因为(1)每个对象包含一个额外的指针(对象的类); (2)有很多簿记数据。 例如,如果使用HashMap来管理对象,那么除了每个对象之外,还会分配一个Map.Entry对象,该对象可以轻松消耗16或20个字节(取决于实现)。

另一方面,仍有希望:你真的需要在内存中维护所有910 MB吗? 难道你不能只是以懒惰的方式构建读取数据的东西吗? 结合WeakReferences我认为你可以解决这个问题。

在32位Windows上,默认情况下,每个应用程序最多可以使用2 GB的虚拟地址空间。 我想这会让-Xmx2048M 。 但是,如果安装了更多RAM,则可以使用引导时参数将虚拟地址空间增加到3 GB。

在boot.ini中,您可以创建一个新的引导选项,如下所示:

 [boot loader]
timeout=5
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - magyar" /noexecute=optin /fastdetect /usepmtimer
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - magyar 3GB" /noexecute=optin /fastdetect /usepmtimer /3GB /USERVA=2800

通过调整/ USERVA = 2800参数,您可以调整机器。 但请注意,某些配置不喜欢此参数中的高值 – 期望崩溃。