tags:

views:

937

answers:

6
+11  Q: 

jvm design decision

Why does the jvm require around 10 MB of memory for a simple hello world but the clr doesn't. What is the trade-off here, i.e. what does the jvm gain by doing this?

Let me clarify a bit because I'm not conveying the question that is in my head. There is clearly an architectural difference between the jvm and clr runtimes. The jvm has a significantly higher memory footprint than the clr. I'm assuming there is some benefit to this overhead otherwise why would it exist. I'm asking what the trade-offs are in these two designs. What benefit does the jvm gain from it's memory overhead?

+1  A: 

CLR is counted as part of the OS so the task manager doesn't report it's memory consumption under the application process.

Tom Hawtin - tackline
If I use mono on a unix it's still uses only a few megs compared to 30 for the jvm
jshen
The CLR starts inside each process, so I doubt this answer is correct.
Austin
Austin: There is a CLR instance in each of process. With both CLR and JRE read-only code is shared between processes. The question is: Is that code counted for each process, or for no processes.
Tom Hawtin - tackline
Ah, I have heard about the code in a DLL being loaded into memory once and then used by several processes. When they are mapped into the process they would defiantly count against the process's virtual memory usage.
Austin
Unless it is part of the OS...
Tom Hawtin - tackline
I don't see why a DLL being part of the operating system would change the memory usage. They get loaded with LoadLibrary just like any other DLL.
Austin
If the DLL is already loaded at system startup, you would not see any additional usage for it when a new process started. The JVM does not own the OS so it can't rely on a pre-loaded library (heck, it can't even rely on a libray mechanism!)
Bill K
+2  A: 

The JVM counts all its shared libraries whether they use memory or not.

Task manager is rather unreliable when it comes to reporting the memory consumption of programs. You should take it as a guide.

Peter Lawrey
The other day my 4 GB Vista machine ran out of memory despite appearing to show less than 1 GB used by applications.
Tom Hawtin - tackline
I don't use windows so I don't use task manager
jshen
+5  A: 

Seems like java is just using more virtual memory.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
amwise   20598  0.0  0.5  22052  5624 pts/3    Sl+  14:59   0:00 mono Test.exe
amwise   20601  0.0  0.7 214312  7284 pts/2    Sl+  15:00   0:00 java Program

I made a test program in C# and in Java that print the string "test" and waits for input. I believe that the resident set size (RSS) value more accurately shows the memory usage. The virtual memory useage (VSZ) is less meaningful.

As I understand it applications can reserve a ton of virtual memory without actually using any real memory. For example you can ask the VirtualAlloc function on Windows to either reserve or commit virtual memory.

EDIT:

Here is a pretty picture from my windows box: alt text

Each app was a simple printf followed by a getchar. Lots of virtual memory usage by Java and CLR. The C version depends on just about nothing, so it's memory usage is tiny relatively.

I doubt it really matters either way. Just pick whichever platform you are more familiar with and then don't write terrible, memory-wasting code. I'm sure it will work out.

EDIT:

This VMMap tool from Microsoft might be useful in figureing out where memory is going.

Austin
RSS of an idle process isn't a great measure either.
Tom Hawtin - tackline
I'm not trying to decide which platform is better for me to use. I'm curious why they made the design decision they did on the jvm side, and what they gained from it.
jshen
All memory usage in a process space is virtual (at least in windows). On a 32bit OS the address space is divided into 2GB Code and 2GB data. Total Private bytes refers to the amount allocated in the data address space of the application. The OS manages how this allocation relates to physical memory.
Brian ONeil
+5  A: 

I don't know if initial memory footprint or a footprint of a Hello World application is important. A difference might be due to the number and sizes of the libraries that are loaded by the JVM / CLR. There can also be an amount of memory that is preallocated for garbage collection pools.

Every application that I know off, uses a lot more then Hello World functionality. That will load and free memory thousands of times throughout the execution of the application. If you are interested in Memory Utilization differences of JVM vs CLR, here are a couple of links with good information

http://benpryor.com/blog/2006/05/04/jvm-vs-clr-memory-allocation/

Memory Management Case study (JVM & CLR)

Memory Management Case study is in Power Point. A very interesting presentation.

Timur Fanshteyn
I'm clearly not stating my question clearly. I'm not interested in memory utilization differences. I'm trying to find out why the jvm requires significantly more memory to start up than essentially every other programming language runtime I've used. I'm assuming there is a reason for it, and I'm curious what it is.
jshen
I doubt that was too intentional. The real power of a virtual machine based language is shown when the application implements business logic and is ran over a period of time. The startup parameters (Initial Memory Utilization and Startup Time) are generally considered secondary importance. One thing I can think of is the initial number of libraries that are loaded on startup is different between JVM and CLR mightbe different. JVM might load more upfront vs CLR loading more on demand. In the longer time, that doesn't make much difference
Timur Fanshteyn
+4  A: 

I guess one reason is that Java has to do everything itself (another aspect of platform independence). For instance, Swing draws it's own components from scratch, it doesn't rely on the OS to draw them. That's all got to take place in memory. Lots of stuff that windows may do, but linux does not (or does differently) has to be fully contained in Java so that it works the same on both.

Java also always insists that it's entire library is "Linked" and available. Since it doesn't use DLLs (they wouldn't be available on every platform), everything has to be loaded and tracked by java.

Java even does a lot of it's own floating point since the FPUs often give different results which has been deemed unacceptable.

So if you think about all the stuff C# can delegate to the OS it's tied to vs all the stuff Java has to do for the OS to compensate for others, the difference should be expected.

I've run java apps on 2 embedded platforms now. One was a spectrum analyzer where it actually drew the traces, the other is set-top cable boxes.

In both cases, this minimum memory footprint hasn't been an issue--there HAVE been Java specific issues, that just hasn't been one. The number of objects instantiated and Swing painting speed were bigger issues in these cases.

Bill K
+2  A: 

JVM loads lots of unnecessary core classes on each run from rt.jar. Unfortunately, the inner-cross dependencies (java.lang <-> java.io) of java packages make it hard to do a partial runtime init. Not to mention the rt.jar itself is over 40MB, needs lots of time for lookup and decompress.

Post Java 6u10 seems to load things a bit smarter (it has a jqs.exe = java quick starter service to keep necessary data in memory and do a faster startup), still Java 7 is told to be better.

The Process Explorer in Windows reports the Private Bytes correctly (Private bytes are those memory regions, which are not shared by any dll).

A slightly bigger annoyance is that after 10 years, JVM still defaults to 64MB memory usage. It is really annoying to use -Xmx almost every time and cannot run demanding programs in jars with a simple double click (unless I alter the file extension assignment's command).

kd304