Technical Blog Post
Largest Possible Maximum Heap Size for WebSphere Java 64 Bit on Linux x86-64
Java on Linux x86-64 supports 48-bit pointers and 256 TB of virtual address space, of which 128 terabytes is reserved for the Kernel, and 128 terabytes for User space.
Maximum Heap in theory on WAS Linux x86-64 would be -Xmx128t with the caveat or requirement of having -Xnocompressedrefs in place also, which essentially means Disabling Compressed References.
Maximum Heap in practice on WAS Linux x86-64 would be approximately -Xmx76t for Java heap because the rest, or 52 TB, is used by Native heap.
*There is no Java heap size restriction from JVM, which potentially means there could be a setting as large as a 64-bit platform can address. But typically in customer memory analysis we notice about 60 percent of memory is used by Java heap and 40 percent by Native heap (including JNI). Now if we extrapolate this information for the Linux-AMD64 platform and apply it towards the user space size of 128 TB, then we could have a Java heap size of around 76 TB and 52 TB for the native heap (assuming this is only process in the Linux-AMD64 system).
When Compressed References are Enabled for 32 bit pointers (-Xcompressedrefs), as-is by Default for performance reasons, the Maximum Heap values will be much lower in gigabytes.
Maximum Heap can be set to -Xmx57g with -Xcompressedrefs in place and at later Java Versions such as Java 8 SR3 onward.
In earlier Java versions and when using -Xcompressedrefs, you can have a Maximum Heap set to -Xmx25g.
More effective heap usage using compressed references in Java 8
*Compressed References previously only supported Java heaps up to 25 GB, but more recent versions of IBM Java 8 SR3 onward support compressed references of Java heap sizes up to 57 GB.
If Compressed References are Disabled (-Xnocompressedrefs) as mentioned before, then the only real limits on the Java heap size are the hardware and operating system limits (for example, 128 TB on Linux x86-64), and more practically, physical memory RAM limits, keeping in mind that every java process JVM will share native memory with the Applications and operating system. There is also a Performance Penalty for Disabling Compressed References which merits mentioning. The range for this penalty is 10-20% relative throughput. Please see the following blog for more information:
*While we are specifically taking about Java Heap, it is important to mention that the WebSphere process PID itself or memory footprint will usually be larger than the Maximum Heap -Xmx value, typically by a factor of (25-35)% on busy Application Servers in Production. The process not only includes the Java Heap itself, but also underlying JNI code and data, JIT code and cache, GC infrastructure, JVM code, Classes/Classloaders, Monitors and Locks, Native and Java Thread Stacks, RAS needs and so forth. Careful consideration should therefore be given to how much Physical Memory is present to backup this Virtual Memory, including all other Java and Native processes being hosted or running on the same machine. If the amount of RAM is considerably less than the virtual address space of 128 TB, then the system will start to SWAP to and from disk long before hitting the limit of 128 TB, making the process run poorly and possibly rendering it unusable.
*Regarding 32 bit WebSphere and Java, we typically recommended Maximum Heap be set in the range of 1024M - 1536M to avoid Native Memory contention. This contention is mostly driven by Windows and its default 2GB user space/2GB kernel split, and some shared libraries sitting right at the 2GB mark. IBM Java introduced the splitHeap option exactly for this reason, and there was always the /3GB kernel option to only give 1GB to the kernel. Due to the complexity, we still generally make conservative recommendations, even though it is possible to have heaps ranging from (2-3) GB with minor modifications, depending up on the OS or platform.