A simple "Hello World" needs 10G virtual memory on a 64-bit machine vs 1G at 32-bit?

The default sizes for initial heap and maximum heap are defined as a percentage of the machine's physical memory, of which a production server nowadays tends to have a whole lot.

You can choose both via the -Xms and -Xmx command line options.


Virtual memory really doesn't matter to you.

The basic difference between 32-bit and 64-bit is that the address space in 64-bit is incredibly large. If 10 GiB looks like a lot to you, note that .NET on 64-bit can use TiBs of memory like this. Yet on 32-bit, .NET is much more conservative (and so is JVM) - the address space is 4 GiB total - that's not a lot.

But it's irrelevant - it doesn't matter. It's just a thing that greatly simplifies programming, and has no negative effect on the host OS whatsoever. It creates a continuous address space for the VM to use, which means that you don't have to fragment the heap (or worse, the stack, where it's more or less impossible - but those tend to be only a MiB or so) as you get to require more "real" memory. When you finally commit the virtual memory, it becomes slightly more real - at that point, it more or less has to be backed by some data storage - be it the page (swap) file or physical RAM.

The point is, the physical location of the memory isn't necessarily continuous, but that's done outside of your reach, and the mapping is generally very fast. On the other hand, having to, say, index an array, that's actually fragmented over 10 different virtual address memory blocks, that's (completely unnecessary) work.

So there you have it - virtual memory is almost free on 64-bit. The basic approach is "if it's there, use it". You're not limiting the other applications, and it saves you quite a bit of work if you do actually end up using it. But until that point comes, you've only got a reservation. It doesn't translate to any physical memory at all. You don't pay for the friends that might come tonight and sit at your table, but you still have the space for them to sit if they do come - and only when they finally come do you actually get "charged".

See this question for more information about the way Java behaves on different machines and with different versions: What is the default maximum heap size for Sun's JVM from Java SE 6? The maximum heap size also determines the amount of virtual memory reserved, because the heap has to be a continuous address space. If it weren't pre-reserved, it could happen that the heap could not expand to this maximum value, because someone else reserved a region of address space in the place the heap has to expand.


It turns out that on a modern computer architecture that uses virtual memory addressing (where the "memory space" an application sees does not actually relate to memory that's actually physically allocated), it really doesn't matter how much of this virtual "memory space" is given to an application upon startup. It doesn't mean that this much memory has been allocated by the system.

If an application sees a virtual address space 10GB large all it signals to the app is that it may use memory addresses up to 10GB if it wants. However, memory is not actually allocated in physical RAM until it is actually written to, and this is done on a page-by-page basis, where a page is a 4kB section of memory. The virtual address space, is just that - completely virtual until actually used.

Let's say an application is given 10GB of address space and it starts using some of it. As a "fresh" - previously untouched - page of this virtual memory is first written to, the system will, on a low level, "map" this virtual page to a section of physical memory, then write it. But that application itself does not have to worry about such details, it just acts as if it has full access to a virtual area of memory.

In the case of Java applications, it's not the application itself but Java that is allocated that address space, and Java simply requests a huge address space by default - the amount it requests is calculated relative to the physical memory size, but not because it has any need to be conservative, but just for practicality - an application is probably not going to want enough heap size to totally bring a server to its knees, so it's operating on the assumption it won't. As I said above this does not mean that this much is "allocated" or that the system has had to expend many resources doing so.


It's not your program using up that memory, it's the Java VM reserving that memory, regardless of which program is loaded.