2

Simple program:

public class SleepTest {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(60 * 1000);
    }
}

Then

$ javac SleepTest.java 
$ java -cp . SleepTest

For OpenJDK 1.6.0_20 this uses 600M of virtual memory on my machine! That is, "top" shows "VIRT" 600M and RES 10m. (I am on Ubuntu 10.04, 32-bit or 64-bit).

For Sun's Java 1.6.0_22 it uses 400M of virtual memory.

What is using all that virtual memory, and how do I lower that usage?

Full "java -version":

OpenJDK:

java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.4) (6b20-1.9.4-0ubuntu1~10.04.1)
OpenJDK Client VM (build 19.0-b09, mixed mode, sharing)

Sun:

$ /usr/lib/jvm/java-6-sun-1.6.0.22/jre/bin/jav -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)

Edit:

Compiling with javac from either package doesn't seem to help.

Adding some code to print used memory is as follows:

private static String megabyteString(long bytes) {
    return String.format("%.1f", ((float)bytes) / 1024 / 1024); 
}
private static void printUsedMemory() {
    Runtime run = Runtime.getRuntime();
    long free = run.freeMemory();
    long total = run.totalMemory();
    long max = run.maxMemory();
    long used = total - free;
    System.out.println("Memory: used " + megabyteString(used) + "M"
            + " free " + megabyteString(free) + "M"
            + " total " + megabyteString(total) + "M"
            + " max " + megabyteString(max) + "M");
}

shows

Sun:

Memory: used 0.3M free 15.2M total 15.5M max 247.5M

OpenJDK:

Memory: used 0.2M free 15.3M total 15.5M max 494.9M

even with -Xmx5m, so it must have a minimum? I've read about defaults before (depends on jvm, virtual machine, a common strategy by default one quarter of physical memory), but is that causing the large virtual memory use and can I not decrease it?

Edit #2:

Adding -Xmx changes things:

$ java -Xmx5m -cp . SleepTest

OpenJDK:

$ java -Xmx5m SleepTest
Memory: used 0.2M free 4.7M total 4.9M max 5.8M

uses "only" 150M of virtual memory for either JVM.

Edit #3:

nos, bestsss, Mikaveli, and maybe others pointed out that virtual memory does not use swap. nos claims the OOM killer is smart enough to go by real memory usage. If those things are true, then I guess I don't care about virtual memory usage. RES (resident size) is small, so I'm good.

Edit #4:

Not sure which answer to accept. Either of these, if it shows up as an answer: "Don't worry about it because virtual memory is cheap" or some explanation of why Java reserves at least 150M in virtual memory no matter what -Xmx or -Xms I give it, even though real memory usage is tiny.

Edit #5:

This is a dup. I voted to close.

Community
  • 1
  • 1
dfrankow
  • 20,191
  • 41
  • 152
  • 214
  • There isn't too much we can determine without more information (same goes for you). You should run the program and get a heap dump of it. Run jmap against the pid running your Java application then have it parsed in a tool like Eclipse MAT. – John Vint Jan 31 '11 at 15:55
  • Another tool you might find useful is VisualVM. https://visualvm.dev.java.net/ – KevinS Jan 31 '11 at 15:59
  • 1
    Why are you worrying about virtual memory size? Do you run out of address space? – biziclop Jan 31 '11 at 16:04
  • John V.: Come on, this is a five line program with nearly no objects. Heap dump shows tiny usage, certainly not 100s of meg. – dfrankow Jan 31 '11 at 16:30
  • @biziclop: first, virtual memory takes disk space. Second, the java process is sometimes being killed, I think by the Linux Out-Of-Memory (OOM) killer, and I think smaller virtual memory usage would take it out of the line of fire. – dfrankow Jan 31 '11 at 16:31
  • @kevin: visualvm shows the same thing as jmap and the logging I show above: almost no memory usage (not many objects, none above 8K, nothing close to 150M). – dfrankow Jan 31 '11 at 16:35
  • @biziclop no, virtual memory does not necessarily take disk space. It might eventuall be swapped out, if the space is actually populated and memory pressuer is high, but just mapping addresses and not touching them does not use disk space. The OOM killer is smart enough to know about this. – nos Jan 31 '11 at 16:37
  • @dfrankow - besides heap, java has direct memory which is a different parameter, code cache, stacks, perm-gem and C alike memory (that is not direct memory), you have limited the heap only. – bestsss Jan 31 '11 at 16:41
  • @dfrankow Sorry, I just realised that what top calls "virtual memory" is "virtual memory actually used". But the answer is simple: java loads a boatload of native libraries and preloads other stuff too that takes up memory. You can't really control it, the `-Xmx` will only set the heap size available to Java code, not the overall VM footprint. – biziclop Jan 31 '11 at 16:41
  • @nos That's what I meant, yes, but I believe top displays used virtual memory, not allocated address space. – biziclop Jan 31 '11 at 16:42
  • 3
    If that virtual memory includes code segment (reading [this](http://serverfault.com/questions/48582/how-is-memory-usage-reported-in-linux/48610#48610) I assume it does), then I wouldn't worry about it. The code doesn't go into the swap as it could always be loaded from the binaries on demand. So it basically means that Java has 150 MB of binaries ready to load the code from, but it won't do that until it's necessary (which could never happen for the most of the code). – Sergei Tachenov Jan 31 '11 at 17:06
  • The ~150 MiB is for the entire JVM process, including the heap allocation for your application - that's why the process will always use more memory than the -Xmx setting that you specify. – Michael Jan 31 '11 at 17:10
  • possible duplicate of [Virtual Memory Usage from Java under Linux, too much memory used](http://stackoverflow.com/questions/561245/virtual-memory-usage-from-java-under-linux-too-much-memory-used) – dfrankow Jan 31 '11 at 17:28
  • @biziclop The VIRT column shows the allocated address space - The man page wording "used virtual memory" just means "allocated address space" . Unless some of your program is actually swapped out, the RES column is more or less showing the physical memory in use - some of that physical memory is shared with other processes though - usually memory mappings of shared libraries, the "SHR" column shows that but its not acurate on Linux. – nos Feb 03 '11 at 22:45
  • @nos Fair enough, I don't know how `top` works beyond what's in the man pages. – biziclop Feb 04 '11 at 00:10

4 Answers4

1

"RES" is resident set size - essentially the physical memory you're using for that process.

From your example, top states that it's using 10 MiB - that's roughly what I'd expect for a -Xmx setting of 5m (the total physical memory used often seems to be double, from my experience of Java on *nix systems.

Are you actually getting any memory issues or are you just concerned about the misleading output from "top"?

Also, the *nix virtual memory includes of the available memory space - physical and swap. If the process isn't using any "swap", then it is only using physical "resident" memory.

Stack Overflow answer to why JVM uses more memory than just heap setting.

Community
  • 1
  • 1
Michael
  • 7,348
  • 10
  • 49
  • 86
  • Explained in @biziclop answer above: trying to avoid OOM killer and huge disk space usage. – dfrankow Jan 31 '11 at 16:36
  • You do realise that *nix virtual memory is the complete memory space, not just swap. Unlike Windows' Virtual "swap" Memory. – Michael Jan 31 '11 at 16:44
  • @Mikaveli: I did not realize! I guess this is a non-issue for me then. – dfrankow Jan 31 '11 at 16:48
  • When you look at the output from "top", in most versions there is a specific column for swap - this is memory using disk space. If your heap is using a very low resident set size (10 MiB), I doubt it'll be spilling over into swap. – Michael Jan 31 '11 at 16:51
  • Ubuntu default top does not have that column I believe. I've never seen it before, but I'm willing to believe it exists. – dfrankow Jan 31 '11 at 16:53
  • The output from "ps" should give you more information - sorry, I can't remember the exact syntax required though. – Michael Jan 31 '11 at 16:59
  • I've added an explanation of *nix virtual memory and included a new link for you, explaining why you process uses more than the -Xmx setting. – Michael Jan 31 '11 at 17:18
  • Note: "top" is really confusing. If I add SWAP column ("o" then "p"), it shows the virtual memory as also being used in swap (contrary to what everyone is saying). However, when I run the program, the "Mem:" and "Swap:" lines of "top" do not change significantly. So, SWAP is including the virtual memory, but I still believe it's not using actual swap disk space. Confusing! – dfrankow Jan 31 '11 at 17:41
  • @dfrankow, it looks like "top" is considering everything that is not in the physical memory to be swapped out, including the code that never actually goes to the swap. You should look at that "Swap:" line instead or use the "free" command. It's really confusing, I agree. – Sergei Tachenov Feb 01 '11 at 09:38
1

$ java -cp . SleepTest -Xmx5m

wow! the -Xmx5m is an argument you can find at public static void main(String[] a). It is parameter to the java program NOT to the VM

move it 1st $ java -Xmx5m -cp . SleepTest

bestsss
  • 11,796
  • 3
  • 53
  • 63
0

Try using -Xms to specify minimum memory?

Alb
  • 3,601
  • 6
  • 33
  • 38
0

The JVM takes some defaults for heap space (that is all that memory usage) in count. This defaults are coming from the machine caracteristics (RAM, cores, etc) and the JVM implementation (Sun/Oracle, OpenJDK).

I think -Xmx5m is too low and the JVM ignores this parameter silently.

Here is a good reference with lots of links to read:

Java Memory explained (SUN JVM)

Community
  • 1
  • 1
PeterMmm
  • 24,152
  • 13
  • 73
  • 111