This have been a long-standing complaint with Java, but it's largely meaningless, and usually based on looking at the wrong Information. The usual phrasing is something like "Hello World on Java takes megabytes! Why does it need? " Well, here's a-a-64-bit JVM claim-to-take over 4 gigabytes ... at least by one form of Measurem Ent.
java-xms1024m-xmx4096m Com.example.Hello
Different Ways to Measure Memory
On Linux, the top command gives your several different numbers for memory. Here's what it says about the Hello world example:
PID USER PR NI VIRT RES SHR S%cpu%MEM time+ COMMAND 2120 kgregory 0 4373m 15m 7152 S 0 0.2 0:00.10 java
- VIRT is the virtual memory space:the sum of everything in the virtual memory map (see below). It's largely meaningless, except when it isn ' t (see below).
- RES is the resident set size:the number of pages it is currently resident in RAM. In almost all cases, this is the only number so you should use when saying "too big." But it's still not a very good number, and especially when the talking about Java.
- SHR is the amount of resident memory, which is shared with other processes. For a Java process, the typically limited to shared libraries and memory-mapped jarfiles. In this example, I-only had one Java process running, so I suspect that the 7k was a result of libraries used by the OS.
- SWAP isn ' t turned on by default, and isn ' t shown here. It indicates the amount of virtual memory that's currently resident on disk, whether or not it's actually in the swap Space. The OS is very good about keeping active pages in RAM, and the only cures for swapping be (1) Buy more memory, or (2) Red UCE the number of processes, so it's best-to-ignore this number.
The situation for Windows Task Manager was a bit more complicated. Under Windows XP, there was "memory Usage" and "Virtual Memory Size" columns, but the official documentation was silent on What they mean. Windows Vista and Windows 7 add more columns, and they ' re actually documented. Of these, the "working Set" measurement is the most useful; It roughly corresponds to the sum of RES and SHR on Linux.
Understanding the Virtual Memory Map
The virtual memory consumed by a process was the total of everything that's in the process memory map. This includes data (eg, the Java heap), but also all of the GKFX libraries and memory-mapped files used by the program. On Linux, you can use the PMAP command to see all of the the things mapped into the process space (from this on off I ' M only g Oing to refer to Linux, because it's what I use; I ' m sure there is equivalent tools for Windows). Here's a excerpt from the memory map of the "Hello World" program; The entire memory map is over lines long, and it's not unusual to a thousand-line list.
0000000040000000 36K r-x--/usr/local/java/jdk-1.6-x64/bin/java0000000040108000 8K rwx--/usr/local/java/jdk-1. 6-x64/bin/java0000000040eba000 676K rwx--[anon]00000006fae00000 21248K rwx--[anon]00000006fc2c0000 62720K rwx--[Anon]0000000700000000 699072K rwx--[anon]000000072aab0000 2097152K rwx--[Anon]00000007aaab0000 34 9504K rwx--[Anon]00000007c0000000 1048576K rwx--[anon] ... 00007fa1ed00d000 1652K r-xs-/usr/local/java/jdk-1.6-x64/jre/lib/rt.jar ... 00007fa1ed1d3000 1024K rwx--[anon]00007fa1ed2d3000 4K-----[anon]00007fa1ed2d4000 1024K rwx--[an On]00007fa1ed3d4000 4K-----[anon] ... 00007fa1f20d3000 164K r-x--/usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so00007fa1f20fc000 1020K-----/usr/l ocal/java/jdk-1.6-x64/jre/lib/amd64/libjava.so00007fa1f21fb000 28K rwx--/usr/local/java/jdk-1.6-x64/jre/lib/ Amd64/libjava.so ... 00007fa1f34aa000 1576K r-x--/lib/x86_64-linux-gnu/libc-2.13.so00007fa1f3634000 2044K-----/lib/x86_64-linux-gnu/libc-2.13.so00007fa1f3833000 16K r-x--/lib/x86_64-linux-gn u/libc-2.13.so00007fa1f3837000 4K rwx--/lib/x86_64-linux-gnu/libc-2.13.so ...
A quick explanation of the Format:each row starts with the virtual memory address of the segment. This was followed by the segment size, permissions, and the source of the segment. This last item is either a file or "anon", which indicates a block of memory allocated via MMAP.
Starting from the top, we have
- The JVM loader (ie, the program, which gets run when you type
java
). This is very small; All it does are load in the shared libraries where the real JVM code is stored.
- A Bunch of anon blocks holding the Java heap and internal data. This was a Sun JVM, so the the heap was broken into multiple generations, and each of the which was its own memory block. Note the JVM allocates virtual memory space based on the
-Xmx
value, this allows it to a contiguous heap. -Xms
The value is used internally to say how much of the heap is ' in use ' When the program starts, and to trigger garbage Collection as that limit is approached.
- A memory-mapped Jarfile, in this case the file that holds the "JDK classes." When you memory-map a JAR, you can access the files within it very efficiently (versus reading it from the start each time ). The Sun JVM would memory-map all JARs on the classpath; If your application code needs to access a JAR, you can also memory-map it.
- Per-thread data for the threads. The 1M block is a thread stack; I don ' t know what goes into the 4K block. For a real app, you'll see dozens if not hundreds of these entries repeated through the memory map.
- One of the shared libraries that holds the actual JVM code. There is several of these.
- The shared library for the C standard library. This is just one of many things, the JVM loads that was not strictly part of Java.
The shared libraries is particularly Interesting:each shared library have at least, segments:a read-only segment cont Aining the library code, and a read-write segment that contains global per-process data for the library (I don ' t know what The segment with no permissions are; I ' ve only seen it on x64 Linux). The read-only portion of the library can be gkfx between all processes this use the library; For example, have libc
1.5M of virtual memory space that can be shared.
When is Virtual Memory Size Important?
The virtual memory map contains a lot of stuff. Some of it is read-only, Some of it are shared, and Some of it are allocated but never touched (eg, almost all of the 4Gb of Heap in this example). But the operating system was smart enough to only load what it needs, so the virtual memory size is largely irrelevant.
Where virtual memory size is important are if you ' re running on a 32-bit operating system, where can-only allocate 2Gb (or, in some cases, 3Gb) of the process address space. In this case you ' re dealing with a scarce resource, and might has to make tradeoffs, such as reducing your heap size in O Rder to memory-map a large file or create lots of threads.
But, given this 64-bit machines is ubiquitous, I don ' t think it'll be long before Virtual Memory Size is a completely I Rrelevant statistic.
When is resident Set Size Important?
Resident Set size is the portion of the virtual memory space, which is actually in RAM. If your RSS grows to is a significant portion of your total physical memory, it might is time to start worrying. If your RSS grows to take up all your physical memory, and your system starts swapping, it's well past time to start worry Ing.
But RSS was also misleading, especially on a lightly loaded machine. The operating system doesn ' t expend a lot of effort to reclaiming the pages used is a process. There ' s little benefit to is gained by doing so, and the potential for an expensive page fault if the process touches the Page in the future. As a result, the RSS statistic may include lots of pages this aren ' t in active use.
Bottom Line
Unless you ' re swapping, don ' t get overly concerned about what the various memory statistics is telling you. With the caveat a ever-growing RSS may indicate some sort of memory leak.
With a Java program, it's far more important to pay attention to what's happening in the heap. The total amount of space consumed was important, and there is some steps so can take to reduce that. More important is the amount of time, spend in garbage collection, and which parts of the heap being getting collect Ed.
Accessing the disk (ie, a database) is expensive, and memory is cheap. If you can trade one for the other, does so.
Http://stackoverflow.com/questions/561245/virtual-memory-usage-from-java-under-linux-too-much-memory-used
JVM Virtual Memory