无法在64位运行64位JVM的Windows 7具有较大的堆大小较大、大小、JVM、Windows

2023-09-08 01:06:36 作者:心因你而碎

这是64位 Windows 7企业版和64位Java 7:

This is 64-bit Windows 7 Enterprise and 64-bit Java 7:

java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b20)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)

这恰好同时使用的C壳:\ WINDOWS \ SystemWOW64 \ CMD.EXE (我错误地认为是64位版本)和与 C:\ WINDOWS \ SYSTEM32 \ CMD.EXE (我刚刚发现,礼貌脉冲星的,是尽管路径名64位应用程序)

This happens using a shell of both C:\Windows\SystemWOW64\cmd.exe (which I incorrectly thought was the 64-bit version) and with C:\Windows\System32\cmd.exe (which I have just found out, courtesy of Pulsar, is a 64-bit application despite the path name).

程序本身很简单:

public class Trivial
{
    public static void main(String[] args) {
        System.out.println("total = " + toMB(Runtime.getRuntime().totalMemory()));
        System.out.println("max   = " + toMB(Runtime.getRuntime().maxMemory()));
    }

    private static long toMB(long bytes) {
        return bytes / (1024L * 1024L);
    }
}

我只是打打闹闹不同的 -Xmx -Xms 参数,看看会发生什么。我会虽然与64位Java在64位的Windows,我可以用pretty的多少不论大小,最大,我想最初的堆,但是这不是发生了什么。

I was just fooling around with different -Xmx and -Xms arguments to see what would happen. I would have though that with 64-bit Java on 64-bit Windows I could use pretty much whatever size max and initial heap I wanted, but that's not what's happening.

的Java -Xmx16G -Xms2G平凡(例如)工作正常。然而,的Java -Xmx16G -Xms4G平凡给我:

java -Xmx16G -Xms2G Trivial (for example) works fine. However, java -Xmx16G -Xms4G Trivial gives me:

Error occurred during initialization of VM
Could not reserve enough space for object heap

怪异(对我来说),的Java -Xmx16G -Xms3G平凡给出了不同的错误:

Weirder (to me), java -Xmx16G -Xms3G Trivial gives a different error:

Error occurred during initialization of VM
Unable to allocate tables for parallel garbage collection for the requested heap size.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

企图分裂 2G之间的差异 3G 来看看是否有在哪里发生这种情况我一个特定的大小尝试的Java -Xmx16G -Xms2900M平凡和它的工作。然后我试图 -Xms2960M 和它的工作。随着 -Xms2970m JVM的崩溃:

Attempting to split the difference between 2G and 3G to see if there was a specific size where this happened I tried java -Xmx16G -Xms2900M Trivial and it worked. Then I tried -Xms2960M and it worked. With -Xms2970m the JVM crashed:

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 1048576 bytes for E in C:\jdk7u2_64p\jdk7u4\hotspot\src\share\vm\utilities/taskqueue.hpp
# An error report file with more information is saved as:
# C:\Users\QuantumMechanic\Temp\hs_err_pid10780.log

这一直持续到 -Xms2995M 时,它切换回无法分配表并行垃圾收集的消息,并坚持认为作为 - XMS 进一步提高。

That continued until -Xms2995M when it switched back to the "unable to allocate tables for parallel garbage collection" message and stuck with that as -Xms was increased further.

可能是什么回事?有没有推出一些从 CMD.EXE (甚至是64位的)施加一些进程大小限制?在Windows(或JVM),需要一个巨大的内存块? (不过,为什么不同的消息)?别的东西?

What could be going on? Does launching something from cmd.exe (even a 64-bit one) impose some process size limits? Is Windows (or the JVM) requiring a single huge memory block? (But then why the different messages)? Something else?

推荐答案

在64位系统中,你有2 ^用户地址空格的63Bytes,但你仍然只能映射量实际内存你有(物理+页面文件+映射文件)。

In a 64-bit system, you have 2^63Bytes of user address space, but you can still only map the amount of actual memory you have (physical + page file + mapped files).

在JVM的创建,它是用C堆的malloc()来请求内存的初始块,然后它要管理块本身。即使没有在堆上的任何对象在所有,到OS的块被使用。

When the JVM creates the heap, it's using C malloc() to request an initial chunk of memory and then it is going to manage the chunk by itself. Even if you don't have any object on the heap at all, to the OS the chunk is being used.

由于您指定的 -Xms ,也就是内存池的最小值,JVM将只是一味要求的内存量的操作系统或失败,因为它不能满足您的命令。

Since you specified -Xms, which is the minimum value of the memory pool, the JVM will simply try to require that amount of memory from the OS or fail as it can't satisfy your command.

我想,如果你想看到64位Java的优势。也许你可以试着打开一个文件大于4GB的随机访问,并将其映射到MappedByteBuffer。

I guess if you want to see the advantage of 64 bit Java. Maybe you can try opening a file larger than 4GB for random access and map it to a MappedByteBuffer.