IS OVER-RESERVING A PROBLEM?
When we look at performance, only committed memory really matters: there is never a perform-
ance problem from reserving too much memory.
However, sometimes you want to make sure that the JVM does not reserve too much memory.
This is particularly true for 32-bit JVMs. Since the maximum process size of a 32-bit application
is 4 GB (or less, depending on the operating system), over-reserving memory can be an issue. A
JVM that reserves 3.5 GB of memory for the heap is left with only 0.5 GB of native memory for
its stacks, code cache, and so on. It doesn't matter if the heap only expands to commit 1 GB of
memory: because of the 3.5 GB reservation, the amount of memory for other operations is limited
to 0.5 GB.
64-bit JVMs aren't limited that way by the process size, but they are limited by the total amount
of virtual memory on the machine. Say that you have a small server with 4 GB of physical
memory and 10 GB of virtual memory and start a JVM with a maximum heap size of 6 GB. That
will reserve 6 GB of virtual memory (plus more for nonheap memory sections). Regardless of
how large that heap actually grows (and the memory that is actually committed), a second JVM
will only be able to reserve less than 4 GB of memory on that machine.
All things being equal, it's convenient to oversize JVM structures and let the JVM optimally use
that memory. But it isn't always feasible.
This difference applies to almost all significant memory that the JVM allocates. The code
cache grows from an initial to a maximum value as more code gets compiled. Permgen or
metaspace is allocated separately and grows between its initial (committed) size and its max-
imum (reserved) size.
One exception to this is thread stacks. Every time the JVM creates a thread, the OS allocates
some native memory to hold that thread's stack, committing more memory to the process
(until the thread exits, at least). Thread stacks, though, are fully allocated when they are cre-
In Unix systems, the actual footprint of an application can be estimated by the resident set
size (RSS) of the process as reported by various OS tools. That value is a good estimate of
the amount of committed memory a process is using, though it is inexact in two ways. First,
the few pages that are shared at the OS level between JVM and other processes (that is, the
text portions of shared libraries) are counted in the RSS of each process. Second, a process
may have committed more memory than it actually paged in at any moment. Still, tracking
the RSS of a process is a good first-pass way to monitor the total memory use. On more re-