I have a couple of simple applications written in java, one of them written to act as a widget. What surprised me how much RAM even small applications use.
I wrote the following to see if it is a bug in my programs, or a general Java issue:
public class ram { public static void main(String[] args){ while(true)System.out.print("Hello World");//while loop to give me time to check RAM usage } }
Then compiled and ran it with java ram
and it gave me the following RAM usage:
The process java (with pid 4489) is using approximately 43.3 MB of memory. 34460 KB [heap] 7088 KB /usr/lib/jvm/java-7-openjdk/jre/lib/amd64/server/libjvm.so 1712 KB /usr/lib/jvm/java-7-openjdk/jre/lib/rt.jar 136 KB [stack:4495] 120 KB /usr/lib/jvm/java-7-openjdk/jre/lib/amd64/libjava.so
Isn't this too high? Especially a heap of 34MB. My system is ArchLinux x86_64 and openjdk-7.
Is there any way to minimise the amount of RAM used by the JVM?
Edit: I tried using the -Xmx flag and this is what I got (1281k was the smallest it would let me start with):
java -Xmx1281k ram The process java (with pid 4987) is using approximately 27.6 MB of memory. 18388 KB [heap]
For comparison, Python2 uses 4.4MB, Mono uses 4.3MB.
The easy way to limit committed memory usage for a JVM is to to use -Xmx to set the maximum heap size. The problem is that if you limit the heap size too severely you are liable to trigger OutOfMemoryError s. Getting the JVM to give back memory is another matter.
Java is also a very high-level Object-Oriented programming language (OOP) which means that while the application code itself is much easier to maintain, the objects that are instantiated will use that much more memory.
What you have specified via the -Xmx switches is limiting the memory consumed by your application heap. But besides the memory consumed by your application, the JVM itself also needs some elbow room. The need for it derives from several different reasons: Garbage collection.
This is because the JVM steadily increases heap usage percentage until the garbage collection process frees up memory again. High heap usage occurs when the garbage collection process cannot keep up. An indicator of high heap usage is when the garbage collection is incapable of reducing the heap usage to around 30%.
I see similar questions to this asked frequently and I have yet to see a satisfactory answer.
The answers I see most frequently are angry "why do you care?" answers. Some people put a lot of thought and effort into making the question and whoever asks it seem stupid.
Some people will answer this question with a long diatribe about the different kinds of memory Java allocates, why it does so, and what command line parameters you should look into. (rarely does anyone get very specific)
The fact is that for small utilities Java is a memory hog on most operating systems. The smaller the utility, the more obvious it really is. Java developers have long been conditioned to deal with or ignore this fact.
The reasons for the seemingly abnormal memory usage are plentiful. Each thread gets a certain amount of memory for it's stack. There are several threads that will get started regardless of how simple a program is for things like garbage cleanup, RMI, etc. On Windows/64-bit that's 1MB per thread. A bunch of classes get loaded by default and all of your classes. I'm sure a lot of other things are happening behind the scenes.
Java has made tradeoff choices that other languages haven't. The load time is slower than most other languages. The initial memory requirement is higher. Strings as they are most commonly used eat up a lot more memory than most people realize. There are countless others. The benefit for many situations really does pay off. Something like Hello World shows off the cost of those choices more than anything else. Benefits like easy multi-threading and near-native performance really don't do you any good with Hello World.
Unfortunately, there's not a lot that you can do to really minimize the memory used by a simple application. There are the aforementioned command line switches and trial and error could shrink your reported usage down to the ~10-15mb level I'm sure, but those choices and time you spend figuring them out aren't going to be applicable to a wide variety of future applications. You'll have to go through the same process again for the next application. Throw in a GUI interface and some logging and another common library or two and your base number will shoot up to 60mb pretty darn quick.
You aren't doing anything wrong. It's just the way things work in Java. You'll get used to it. You'll choose another language on occasion because of it, and that's OK too.
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