In 1.3.0 win32 the maximum possible heap limit is about 1.2GB,
although the OS supports 2GB address space per process. This
is caused by the way the JDK DLLs are rebased, and a simple
change will increase the maximum possible heap limit to
1.6 or even 1.9GB.
The rebasing to 0x50000000 is done in rebase.sh in the 1.3 builds.
Detailed explanation below.
In NT4.0 standard, the default per process limit is 2GB (with the upper
half 2GB address range reserved for the OS). In practice it is a bit
smaller since each thread reserves an address range corresponding to
its maximum stack size.
NT4.0 Enterprise Edition and Windows 2000 Server supports a 3GB mode
(with 1GB address range reserved for the OS). Windows 2000 Advanced
Server supports up to 32GB, then one has to use special "windowing"
APIs to get at the memory.
Both Classic VM and HotSpot VM reserves a contiguous address range for
the object heap. NT places kernel DLLs in the 0x7 part of the address
space in both the 2GB and 3GB mode, meaning that NT will only give
<2 GB of contiguous address space. So 2GB is a hard JVM heap limit
The reason one currently can only get about 1.2GB heap is due to the
way the JDK DLLs are rebased. Microsoft system DLLs start at 0x77000000.
Microsoft recommends an application rebase starting address of 0x60000000.
Netscape is rebased at 0x60000000, and in order to avoid address
conflicts for the JVM plugin, a JDK base of 0x50000000 was chosen at
some point (by Anand Palaniswamy, I think).
Here is a dump of the DLL layout for JDK1.3.0 using listdlls.exe
Base Size Path
0x00400000 0x5000 d:\jdk1.3\bin\java.exe
0x503f0000 0x10b000 d:\jdk1.3\jre\bin\hotspot\jvm.dll
0x50220000 0x7000 d:\jdk1.3\jre\bin\hpi.dll
0x50380000 0xd000 d:\jdk1.3\jre\bin\verify.dll
0x50250000 0x17000 d:\jdk1.3\jre\bin\java.dll
0x50390000 0xd000 d:\jdk1.3\jre\bin\zip.dll
0x6bd00000 0x21000 C:\WINNT\System32\cwbaudll.dll
0x77f60000 0x5e000 C:\WINNT\System32\ntdll.dll
0x77dc0000 0x3f000 C:\WINNT\system32\ADVAPI32.dll
0x77f00000 0x5e000 C:\WINNT\system32\KERNEL32.dll
0x77e70000 0x54000 C:\WINNT\system32\USER32.dll
0x77ed0000 0x2c000 C:\WINNT\system32\GDI32.dll
0x77e10000 0x57000 C:\WINNT\system32\RPCRT4.dll
0x78000000 0x40000 C:\WINNT\system32\MSVCRT.dll
0x77fd0000 0x2a000 C:\WINNT\System32\WINMM.dll
So that leaves 0x50000000 - 0x00400000 = 1276MB contiguous address space.
One could rebase everything at, say, 0x6D000000. That will not conflict
with Netscape and would allow a maximum heap size of 1.6GB on NT.
Run the following command:
rebase.exe -b 0x6D000000 \jdk1.3\jre\bin\*.dll \jdk1.3\jre\bin\hotspot\jvm.dll
On my NT box that enables using -Xmx1650m. The offending file is now
\WINNT\System32\cwbaudll.dll. I have no idea why that file doesn't
have a base in the 0x77 range? It is an audio driver of some sort.
Rebasing the JDK dlls to 0x76000000 actually works (although probably not
recommended practice by Microsoft), so if the audio driver wasn't present
we could get -Xmx1900m to work.
rebase.exe is from Microsoft Visual Studio.
listdlls.exe is from http://www.sysinternals.com.