views:

337

answers:

3

I ran the following method Runtime.getRuntime().maxMemory() and gave 85196800.

However, I then ran top from the command line and it showed

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                       
 8672 root      20   0 1284m 156m 4296 S  0.3 60.9   0:33.35 java

Doesn't that show 156M of ram used? Any ideas what is going on?

+2  A: 

From the documentation,

maxMemory() - Returns the maximum amount of memory that the Java virtual machine will attempt to use.

Top only shows the amount of (virtual) memory that the system has allocated to the process - you are asking Java how much it could attempt to use in the worst case.

In general, querying the JVM and/or system for information on actual memory used is not reliable. For example, top's numbers may include memory allocated but not used or paged out. It can also include things like shared libraries, where a 10MB library may count for two processes' allocations but only have one physical copy in memory. (For example)

What are you trying to do?

Steven Schlansker
Isn't that what VIRT shows? I thought RES showed the ACTUAL memory used, which is more than what JVM will attempt to use, doesn't make sense
erotsppa
The problem here is that maxMemory is suppose to return a number that I can expect the jvm not to exceed. But it does, the RES number for my java process keeps growing and bringing my server to a halt!! Why is it not following the maxMemory rule?
erotsppa
What command line options are you passing to your server? Specifically, -Xmx and -Xms.Top is probably reporting some things that the function call isn't - I'd guess that the RES field on top does include shared libraries but the JVM doesn't count that towards its own usage. Stack space also probably falls into that category...You probably shouldn't rely on asking the Runtime class for how much memory it would use. I'd tune -Xmx and -Xms instead, and have sufficient swap available to handle any temporary overages.
Steven Schlansker
I'm using the default settings, which means the heap should not exceed 83Mb, how did I get 1284Mb in VIRT??
erotsppa
VIRT doesn't really reflect much at all. I just wrote a program that malloc()ed a lot of memory but never used it, which causes a ridiculous VIRT measurement but hardly uses any real memory at all.
Steven Schlansker
A: 

Runtime.getRuntime().maxMemory() is returning an estimate of the maximum heap size, not the total amount of memory that will be consumed by the entire process. Native memory, native libraries, etc. will contribute to the process size but not to maxMemory().

bkail
A: 

The Javadocs for that method are wrong, or at least very misleading. This Sun bug report explains.

The other point is that the 156Mb shown as RES is the current "resident set" size; i.e. the amount of physical RAM currently attributed to the application. This number is liable to increase and decrease depending on the virtual memory demands of the system services / daemons and applications running on the machine. The numbers that the JVM purports to report are the JVM's virtual memory allocation.

Suffice it to say that this is all as clear as mud, and probably not worth your effort to try to figure it out. If you really care, pay attention to what top, vmstat and so on tell you, and ignore the JVM numbers.

Stephen C