39

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.

Vivo
  • 391
  • 1
  • 3
  • 5
  • possible duplicate of [How to set the maximum memory usage for JVM?](http://stackoverflow.com/questions/1493913/how-to-set-the-maximum-memory-usage-for-jvm) – dsgriffin Dec 03 '12 at 21:42
  • 7
    Who cares? Virtual memory is essentially free. Modern systems can make huge amounts of it at near-zero cost. This is like trying to breathe less air. (Note that this is not measuring physical memory, RAM, but just measuring virtual memory, address space.) – David Schwartz Dec 03 '12 at 21:42
  • 43MB is not surprising, since JVM reserve enough memory for possible future load. but it should be fine if you set max mem to just a few MB – irreputable Dec 03 '12 at 21:45
  • The JVM *does* use [relatively] lots of memory. While David does make a point about it being "virtual", I think this may overshadow the overhead's involved with a typical Java environment compared to a native application (especially when the application "does nothing" but starts) - so how does this compare to physical usage? I know not .. –  Dec 03 '12 at 21:45
  • @TomG Sometimes it is not about cost of RAM, because some devices can only have so much of it (Raspberry Pi : 265/512MB RAM, my netbook : 2GB) – Vivo Dec 03 '12 at 22:21
  • Interesting question. I quickly tried some parameters and ran your program on MacOS with 17MB instead of 40MB just with 3 params: -Xmx2m -Xms2m -Xint. I think there is a lot to squeeze if you examine all java command line parameters. – Assen Kolov Dec 03 '12 at 22:52
  • @AssenKolov The best I got was 19MB with `java -Xmx1281k -Xms1281k -Xss160k -Xint -Xnoclassgc -Xrs -Xbatch ram` Even with just an empty while loop and no variables/print statements, the lowest I got was 16.7MB – Vivo Dec 03 '12 at 23:40
  • @Vivo: which program did you use to list the memory usage of your java process? – jansohn Oct 21 '20 at 13:24

2 Answers2

117

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.

Steve Kallestad
  • 3,484
  • 2
  • 23
  • 31
  • 23
    Thanks for taking the time to provide a balanced answer with none of the usual rage (in either direction) +1 – Basic Jan 07 '14 at 19:27
  • 1
    This is a brilliant answer. Seems to solve the conundrum. – bluelurker Dec 01 '15 at 10:54
  • 4
    How come C# uses less memory? For example I usually see intellij, Eclipse or netbeans use 1gb of ram,but Visual Studio only uses 300mb. Also I've seen other c# programs such as paint. Net, and according to task manager they also use very little memory. – Pavel Jan 27 '16 at 19:48
  • 1
    @pavel maybe c# being run only on windows has better optimisation, eg utilising system resources etc, on the other hand JVM needs to work on other platforms has to implement their own magic. I might be wrong tho. – James Lin Feb 26 '17 at 20:19
  • @Pavel I'm pretty sure VisualStudio is coded in C++, not in C#. Not sure about Paint.NET. – Didier A. Jul 13 '17 at 06:37
  • @Didier you are wrong. Visual studio is written in c#, using wpf – Pavel Jul 13 '17 at 06:53
  • @Pavel Not according to Wikipedia and this website: http://www.lextrait.com/Vincent/implementations.html The core of VisualStudio is in C++. Only the UI widgets have been transitioned over to C# with WPF. – Didier A. Jul 13 '17 at 06:56
  • @Didier and what is that core? What does it consist of? – Pavel Jul 13 '17 at 07:09
  • The code base is proprietary, so its hard to say, but its most probably all the actual logic. You can read more about it here: https://blogs.msdn.microsoft.com/visualstudio/2010/02/16/wpf-in-visual-studio-2010-part-1-introduction/ . They just mention that they separated the core business logic from the presentation layer. So the presentation layer is WPF, the core logic is mostly C++, and it sounds like some components might be running VB. I'd suspect things like search, file buffers, outlines, etc. are probably C++. – Didier A. Jul 13 '17 at 07:41
  • Also Visual Studio uses a bunch of dlls already loaded by Windows!?!?!? – user432024 Oct 25 '17 at 04:35
  • 3
    Thank You! Best answer I got. Every other answer is like "cause new computer's have enough RAM, so it doesn't matter". I'm a C++ programmer, that's why this is an interesting topic to me. Really, thanks a lot. – Gabor Szita Dec 31 '20 at 11:28
  • I have a simple java rest that is occupying 4GB of RAM and I don't understand why – manudicri Oct 20 '21 at 08:48
10

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
Community
  • 1
  • 1
stmoebius
  • 662
  • 11
  • 30