Arnar Gunnarsson
Arnar Gunnarsson

Reputation: 131

Java memory usage on Linux

I'm running a handfull of Java Application servers that are all running the latest versions of Tomcat 6 and Sun's Java 6 on top of CentOS 5.5 Linux. Each server runs multiple instances of Tomcat.

I'm setting the -Xmx450m -XX:MaxPermSize=192m parameters to control how large the heap and permgen will grow. These settings apply to all the Tomcat instances across all of the Java Application servers, totaling about 70 Tomcat instances.

Here is a typical memory usage of one of those Tomcat instances as reported by Psi-probe

Eden           = 13M
Survivor       = 1.5M 
Perm Gen       = 122M 
Code Cache     = 19M 
Old Gen        = 390M 
Total          = 537M

CentOS however is reporting RAM usage for this particular process at 707M (according to RSS) which leaves 170M of RAM unaccounted for.

I am aware that the JVM itself and some of it's dependancy libraries must be loaded into memory so I decided to fire up pmap -d to find out their memory footprint. According to my calculations that accounts for about 17M.

Next there is the Java thread stack, which is 320k per thread on the 32 bit JVM for Linux. Again, I use Psi-probe to count the number of threads on that particular JVM and the total is 129 threads. So 129 + 320k = 42M

I've read that NIO uses memory outside of the heap, but we don't use NIO in our applications.

So here I've calculated everything that comes to (my) mind. And I've only accounted for 60M of the "missing" 170M.

What am I missing?

Upvotes: 13

Views: 8253

Answers (5)

ahawtho
ahawtho

Reputation: 704

Arnar, the JVM also mmap's all jar files in use, which will use NIO and will contribute to the RSS. I don't believe those are accounted for in any of your measurements above. Do you by chance have a significant number of large jar files? If so, the pages used for those could be your missing memory.

Upvotes: 0

Mike
Mike

Reputation: 2464

Try using the incremental garbage collector, using the -Xincgc command line option. It's little more aggressive on the whole GC efforts, and has a special happy little anomaly: it actually hands back some of its unused memory to the OS, unlike the default and other GC choices ! This makes the JVM consume a lot less memory, which is especially good if you're running multiple JVM's on one machine. At the expense of some performance - but you might not notice it. The incgc is a little secret it seems, because noone ever brings it up... It's been there for eons (90's even).

Upvotes: 3

Christopher Hunt
Christopher Hunt

Reputation: 2081

Not a direct answer, but, have you also considered hosting multiple sites within the same Tomcat instance? This could save you some memory at the expense of some additional configuration.

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533442

Java allocates as much virtual memory as it might need up front, however the resident side will be how much you actually use. Note: Many of the libraries and threads have their own over heads and while you don't use direct memory, it doesn't mean none of the underlying system do. e.g. if you use NIO, it will use some direct memory even if you use heap ByteBuffers.

Lastly, 100 MB is worth about £8. It may be that its not worth spending too much time worrying about it.

Upvotes: 1

Anil Vishnoi
Anil Vishnoi

Reputation: 1392

Arnar, In JVM initialization process JVM will allocate a memory (mmap or malloc) of size specified by -Xmx and MaxPermSize,so anyways JVM will allocate 450+192=642m of heap space for application at the start of the JVM process. So java heap space for application is not 537 but its 642m.So now if you do the calculation it will give you your missing memory.Hope it helps.

Upvotes: 2

Related Questions