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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/987219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:55:16  来源:igfitidea点击:

Maximum amount of memory per Java process on Windows?

javawindows

提问by Jay R.

What is the maximum heap size that you can allocate on 32-bit Windows for a Java process using -Xmx?

您可以在 32 位 Windows 上为 Java 进程分配的最大堆大小是-Xmx多少?

I'm asking because I want to use the ETOPO1 data in OpenMapand the raw binary float file is about 910 MB.

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

采纳答案by Gili Nachum

There's nothing better than an empirical experiment to answer your question. I've wrote a Java program and run it while specifying the XMX flag (also used XMS=XMX to force the JVM pre-allocate all of the memory). To further protect against JVM optimizations, I've actively allocate X number of 10MB objects. I run a number of test on a number of JVMs increasing the XMX value together with increasing the number of MB allocated, on a different 32bit operating systems using both Sun and IBM JVMs, here's a summary of the results:

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

OS:Windows XP SP2, JVM: Sun 1.6.0_02, Max heap size: 1470 MB
OS: Windows XP SP2, JVM: IBM 1.5, Max heap size: 1810 MB
OS: Windows Server 2003 SE, JVM: IBM 1.5, Max heap size: 1850 MB
OS: Linux 2.6, JVM: IBM 1.5, Max heap size: 2750 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

Here's the detailed run attempts together with the allocation class helper source code:

下面是详细的运行尝试以及分配类帮助器源代码:

WinXP SP2, SUN JVM:

WinXP SP2,SUN JVM:

C:>java -version
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode)

java -Xms1470m -Xmx1470m Class1 142 ... about to create object 141 object 141 created

C:>java -Xms1480m -Xmx1480m Class1 145 Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.

WinXP SP2、IBM JVM
 
C:>c:\ibm\jdk\bin\java.exe -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pwi32devifx-20070323 (if
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 enabled)
J9VM - 20070322_12058_lHdSMR
JIT  - 20070109_1805ifx3_r8
GC   - WASIFIX_2007)
JCL  - 20070131

c:\ibm\jdk\bin\java.exe -Xms1810m -Xmx1810m Class1 178 ... about to create object 177 object 177 created

C:>c:\ibm\jdk\bin\java.exe -Xms1820m -Xmx1820m Class1 179 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate he ap. 1820M requested Could not create the Java virtual machine.

Win2003 SE、IBM JVM
C:>"C:\IBM\java" -Xms1850m -Xmx1850m Class1
sleeping for 5 seconds.
Done.

C:>"C:\IBM\java" -Xms1880m -Xmx1880m Class1 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate he ap. 1880M requested Could not create the Java virtual machine.

Linux 2.6,IBM JVM
[root@myMachine ~]# /opt/ibm/java2-i386-50/bin/java -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pxi32dev-20060511 (SR2))
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20060504 (JIT enabled)
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 Initialization error for library j9gc23(2): Failed to instantiate heap. 2800M requested Could not create the Java virtual machine.

Here's the code:

这是代码:


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.");
    }

}

回答by Itay Maman

As noted in the question mentioned in the comment, there is a practical limit, circa 1200 MB.

正如评论中提到的问题所指出的,有一个实际限制,大约 1200 MB。

However the situation you're describing has more depth to it than sheer memory size.

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

When you read a 910 MB binary data and build a network objects off of it (as opposed to just maintaining the data as an array of bytes), you end up consuming much more memory than 910 MB. A reasonable estimate would be that the in-memory representation will consume twice as much memory - that's because (1) each object contains an additional pointer (to the class of the object); and (2) there's a lot bookkeeping data. For instance if you use a HashMap to manage your objects then in addition to each object you also allocate a Map.Entry object which can easily consume 16 or 20 bytes (implementation dependent).

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

On the other hand, there's still hope: do you really need to maintain all 910 MB in memory? Can't you just build something that reads the data in a lazy manner? Combined with WeakReferences I think you can pull this off.

另一方面,还有希望:您真的需要在内存中保留所有 910 MB 吗?你不能只是构建一些以懒惰方式读取数据的东西吗?结合 WeakReferences 我认为你可以做到这一点。

回答by akarnokd

On 32-bit Windows, by default, every application can use up to 2 GB virtual address space. I guess this makes -Xmx2048M. However, if you have more RAM installed, you can increase the virtual address space up to 3 GB by using boot time parameters.

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

In boot.ini, you can create a new boot options like this:

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

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

Here by adjusting the /USERVA=2800 parameter, you can tune your machine. But be aware that some configurations don't like high values in this parameter - expect crashes.

这里通过调整 /USERVA=2800 参数,可以对机器进行调优。但请注意,某些配置不喜欢此参数中的高值 - 预计会发生崩溃。

回答by Peter Lawrey

For a large file I suggest you use a memory mapped file. This doesn't use heap space (or very little) so maximum heap size shouldn't be a problem in this case.

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

回答by Fortyrunner

We have recently ported from Windows to Linux (because of VM size issues).

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

I have heard of lots of numbers thrown around in the past for Windows VM size (1200, 1400, 1600, 1800). On our Windows Servers (2003), in our environment, with our applications, ... I have never successfully used more than 1280MB. Beyond that our application started exhibiting GC and OOM issues.

我听说过去有很多关于 Windows VM 大小的数字(1200、1400、1600、1800)。在我们的 Windows Servers (2003) 上,在我们的环境中,在我们的应用程序中,...我从未成功使用超过 1280MB。除此之外,我们的应用程序开始出现 GC 和 OOM 问题。

Everytime I got a new VM version I tried changing the number and it never varied.

每次我获得一个新的 VM 版本时,我都会尝试更改该数字,但它从未改变过。

You have a 900MB file now, what if the file increases to 1300MB? What will you do?

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

You have a number of options

您有多种选择

  1. Port to Linux/Solaris. This just needs hardware/software and what is often a simple porting exercise.
  2. Use 64bit Windows. This may not be free of GC issues though - I have heard of different tales with 64bit vms.
  3. Redesign the app to process the file differently, Can you split the file logically in some way, can you read the file in chunks and process it differently etc?
  1. 移植到 Linux/Solaris。这只需要硬件/软件以及通常是一个简单的移植练习。
  2. 使用 64 位 Windows。虽然这可能不是没有 GC 问题 - 我听说过 64 位虚拟机的不同故事。
  3. 重新设计应用程序以不同方式处理文件,您能否以某种方式在逻辑上拆分文件,您是否可以分块读取文件并以不同方式处理它等?

Other people using OpenMap must have encountered this issue. Can you tap into their knowledge and not re-invent any wheels?

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