Windows中每个Java进程的最大内存量?
使用-Xmx
可以在32位Windows上为Java进程分配的最大堆大小是多less?
我问,因为我想在OpenMap中使用ETOPO1数据,原始二进制浮点文件大约是910Mb。
没有什么比用经验实验来回答你的问题更好了。 我写了一个Java程序并运行它,同时指定XMX标志(也使用XMS = XMX来强制JVM预分配所有的内存)。 为了进一步防止JVM优化,我主动分配X个10MB的对象。 我使用Sun和IBM JVM在不同的32位操作系统上对许多JVM执行了一系列testing,从而增加了XMX值,同时增加了分配的MB的数量,以下是对结果的总结:
操作系统: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运行时环境(build 1.6.0_02-b06) Java HotSpot(TM)客户端虚拟机(版本1.6.0_02-b06,混合模式)
java -Xms1470m -Xmx1470m Class1 142
…
即将创build对象141
创build对象141
C:> java -Xms1480m -Xmx1480m Class1 145
VM初始化期间发生错误
无法为对象堆预留足够的空间
无法创buildJava虚拟机。
WinXP SP2,IBM JVM
C:> c:\ ibm \ jdk \ bin \ java.exe -version java版本“1.5.0” Java(TM)2运行时环境,标准版(build pwi32devifx-20070323(if ix 117674:SR4 + 116644 + 114941 + 116110 + 114881)) IBM J9 VM(内部版本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
…
即将创build对象177
创build对象177
C:> c:\ ibm \ jdk \ bin \ java.exe -Xms1820m -Xmx1820m Class1 179
JVMJ9VM015W库j9gc23(2)的初始化错误:无法实例化他
AP。 1820M要求
无法创buildJava虚拟机。
Win2003 SE,IBM JVM
C:>“C:\ IBM \ java”-Xms1850m -Xmx1850m Class1 睡5秒。 完成。
C:>“C:\ IBM \ java”-Xms1880m -Xmx1880m
1类
JVMJ9VM015W库j9gc23(2)的初始化错误:无法实例化他
AP。 1880M要求
无法创buildJava虚拟机。 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(内部版本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要求
无法创buildJava虚拟机。
代码如下:
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 <numOfObjects; i++) { System.out.println("about to create object "+i); arr[i] = new BigObject(); System.out.println("object "+i+" created"); } System.out.println("sleeping for 5 seconds."); try { Thread.sleep(5000); }catch (Exception e) {e.printStackTrace();} System.out.println("Done."); } }
对于大文件,我build议你使用内存映射文件。 这不使用堆空间(或很less),所以在这种情况下最大的堆大小不应该是一个问题。
我们最近从Windows移植到Linux(由于VM大小问题)。
我听说过去Windows VM大小(1200,1400,1600,1800)大量的数字。 在我们的Windows服务器(2003),在我们的环境中, 与我们的应用程序 ,…我从来没有成功地使用超过1280MB。 除此之外,我们的应用程序开始展示GC和OOM问题。
每次我得到一个新的VM版本,我试图改变的数字,它从来没有变化。
你现在有一个900MB的文件,如果文件增加到1300MB会怎么样? 你会怎么做?
你有很多select
- 端口到Linux / Solaris。 这只需要硬件/软件,通常是一个简单的移植练习。
- 使用64位Windows。 这可能不是免费的GC问题 – 我听说过与64位vms不同的故事。
- 重新devise应用程序以不同的方式处理文件,你可以以某种方式逻辑分割文件,你可以读取文件块并以不同的方式进行处理吗?
其他使用OpenMap的人必须遇到这个问题。 你可以挖掘他们的知识,而不是重新发明任何车轮?
正如在评论中提到的问题所指出的那样,实际的限制大约是1200mb。
然而,你所描述的情况比内存大小更深入。
当你读取一个910MB的二进制数据,并build立一个networking对象(而不是仅仅维护数据为一个字节数组),你最终消耗比910MB更多的内存。 一个合理的估计是内存中的表示会消耗两倍的内存 – 这是因为(1)每个对象包含一个额外的指针(对象的类)。 和(2)有很多簿记数据。 例如,如果使用HashMap来pipe理对象,那么除了每个对象之外,还要分配一个可轻松使用16或20个字节(依赖于impl)的Map.Entry对象。
另一方面,仍然有希望:你真的需要保持所有910MB的内存? 难道你不能build立一些懒惰的方式读取数据? 结合WeakReferences我认为你可以把它closures。
在32位Windows中,默认情况下,每个应用程序最多可以使用2GB的虚拟地址空间。 我想这使得-Xmx2048M。 但是,如果您有更多的内存,可以使用启动时间参数将虚拟地址空间增加到3GB。
在boot.ini中,你可以创build一个像这样的新的启动选项:
[引导装载程序]
超时= 5
默认=多(0)磁盘(0)RDISK(0)分区(1)\ WINDOWS
[操作系统]
多个(0)磁盘(0)rdisk(0)分区(1)\ WINDOWS =“Microsoft Windows XP Professional – magyar”/ noexecute = optin / fastdetect / usepmtimer
(0)磁盘(0)rdisk(0)分区(1)\ WINDOWS =“Microsoft Windows XP Professional – magyar 3GB”/ noexecute = optin / fastdetect / usepmtimer / 3GB / USERVA = 2800
这里通过调整/ USERVA = 2800参数,可以调整你的机器。 但请注意,某些configuration不喜欢此参数中的高值 – 预计崩溃。