In the course of profiling a 64-bit Java app that's having some issues, I notice that the profiler itself (YourKit) is using truly colossal amounts of memory. What I've got in the YourKit launch script is:
JAVA_HEAP_LIMIT="-Xmx3072m -XX:PermSize=256m -XX:MaxPermSize=768m"
Naively, assuming some overhead, this would lead me to guess that YourKit is going to use a max of something maybe a bit over four GB. However, what I actually see in PS is:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
dmoles 31379 4.4 68.2 14440032 8321396 ? Sl 11:47 10:42 java -Xmx3072m -XX:PermSize=256m -XX:MaxPermSize=768m -XX:+HeapDumpOnOutOfMemoryError -Dyjp.probe.table.length.limit=20000 -Xbootclasspath/a:/home/dmoles/Applications/yjp-9.5.6/bin/../lib/tools.jar -jar /home/dmoles/Applications/yjp-9.5.6/bin/../lib/yjp.jar
That's a virtual size of nearly 14 GB and a resident size of nearly 8 GB -- nearly 3x the Java heap.
Now, I've got enough memory on my dev box to run this, but going back to the original memory problem I'm trying to diagnose: How do I know how much Java heap I have to play with?
Clearly, if the customer has, say, 16 GB physical RAM, it's not a great idea for me to tell them to set -Xmx
to 16 GB.
So what is a reasonable number? 12 GB? 8 GB?
And how do I estimate it?
The theoretical limit is 2^64 bytes, which is 16 exabytes (1 exabyte = 1024 petabytes, 1 petabyte = 1024 terabytes). However, most OS's can't handle that. For instance, Linux can only support 64 terabytes of data. Note: We don't recommend you exceed 2 GB of in use JVM heap.
The default Java heap size is 768 MB, which supports fewer than 50,000 pairs. If you increase the Java heap size by 256 MB, support increases by 25,000 pairs. You can continue to increase the Java heap size until you reach the maximum heap size. The path_prefix /opt/IBM/CSM/wlp/usr/server/csmServer/jvm.
You can control the heap size with the following JVM parameters: -Xms value. -Xmx value. -XX:MinHeapFreeRatio= minimum.
Clearly, if the customer has, say, 16 GB physical RAM, it's not a great idea for me to tell them to set -Xmx to 16 GB.
If the customer was running nothing else significant on his/her machine, then setting the heap size to 16G isn't necessarily a bad idea. It depends on what the application is doing.
So what is a reasonable number? 12 GB? 8 GB?
The ideal number would be to have "JVM max heap + JVM non-heap overheads + OS + other active applications' working sets + buffer cache working set" add up to the amount of physical memory. But the problem is that none of those components (apart from the max heap size) can be pinned down without detailed measurements on the customer's machine ... while the application is running on the actual problem.
And how do I estimate it?
The bottom line is that you can't. The best you can do is to guess ... and be conservative.
An alternative approach is to estimate how much heap the application actually needs for the problem it is trying to solve. Then add an extra 50 or 100 percent to give the GC room to work efficiently. (And then tune ...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With