High Java memory usage even for small programs

31,783

Solution 1

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.

Solution 2

There are several reasons for this:

  1. The java runtime is a rather complex program in itself. It needs to take the byte code of your Java program (the output from javac), translate it into machine code for the system it is running on, there's an optimizer for that, there are interfaces for debugging, etc.
  2. Although your program is rather small, Java will still load many classes from its standard library. You can observe this by starting it using 'java -verbose:class ram'
  3. Java allocates a great bunch of memory for your program in advance - it cannot know how much memory it will actually need. This is, among others, governed by the -Xmx option. There are several types of such memory. To find out more about them, you can use the JConsole tool, which is included in the JDK's bin folder. You can read more about it at java.sun.com. A summary of the memory areas used by Java is also given at this stackoverflow question
Share:
31,783
Admin
Author by

Admin

Updated on July 02, 2020

Comments

  • Admin
    Admin almost 4 years

    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.