A simple "Hello World" needs 10G virtual memory on a 64-bit machine vs 1G at 32-bit?

10,783

Solution 1

The default sizes for initial heap and maximum heap are defined as a percentage of the machine's physical memory, of which a production server nowadays tends to have a whole lot.

You can choose both via the -Xms and -Xmx command line options.

Solution 2

Virtual memory really doesn't matter to you.

The basic difference between 32-bit and 64-bit is that the address space in 64-bit is incredibly large. If 10 GiB looks like a lot to you, note that .NET on 64-bit can use TiBs of memory like this. Yet on 32-bit, .NET is much more conservative (and so is JVM) - the address space is 4 GiB total - that's not a lot.

But it's irrelevant - it doesn't matter. It's just a thing that greatly simplifies programming, and has no negative effect on the host OS whatsoever. It creates a continuous address space for the VM to use, which means that you don't have to fragment the heap (or worse, the stack, where it's more or less impossible - but those tend to be only a MiB or so) as you get to require more "real" memory. When you finally commit the virtual memory, it becomes slightly more real - at that point, it more or less has to be backed by some data storage - be it the page (swap) file or physical RAM.

The point is, the physical location of the memory isn't necessarily continuous, but that's done outside of your reach, and the mapping is generally very fast. On the other hand, having to, say, index an array, that's actually fragmented over 10 different virtual address memory blocks, that's (completely unnecessary) work.

So there you have it - virtual memory is almost free on 64-bit. The basic approach is "if it's there, use it". You're not limiting the other applications, and it saves you quite a bit of work if you do actually end up using it. But until that point comes, you've only got a reservation. It doesn't translate to any physical memory at all. You don't pay for the friends that might come tonight and sit at your table, but you still have the space for them to sit if they do come - and only when they finally come do you actually get "charged".

See this question for more information about the way Java behaves on different machines and with different versions: What is the default maximum heap size for Sun's JVM from Java SE 6? The maximum heap size also determines the amount of virtual memory reserved, because the heap has to be a continuous address space. If it weren't pre-reserved, it could happen that the heap could not expand to this maximum value, because someone else reserved a region of address space in the place the heap has to expand.

Solution 3

It turns out that on a modern computer architecture that uses virtual memory addressing (where the "memory space" an application sees does not actually relate to memory that's actually physically allocated), it really doesn't matter how much of this virtual "memory space" is given to an application upon startup. It doesn't mean that this much memory has been allocated by the system.

If an application sees a virtual address space 10GB large all it signals to the app is that it may use memory addresses up to 10GB if it wants. However, memory is not actually allocated in physical RAM until it is actually written to, and this is done on a page-by-page basis, where a page is a 4kB section of memory. The virtual address space, is just that - completely virtual until actually used.

Let's say an application is given 10GB of address space and it starts using some of it. As a "fresh" - previously untouched - page of this virtual memory is first written to, the system will, on a low level, "map" this virtual page to a section of physical memory, then write it. But that application itself does not have to worry about such details, it just acts as if it has full access to a virtual area of memory.

In the case of Java applications, it's not the application itself but Java that is allocated that address space, and Java simply requests a huge address space by default - the amount it requests is calculated relative to the physical memory size, but not because it has any need to be conservative, but just for practicality - an application is probably not going to want enough heap size to totally bring a server to its knees, so it's operating on the assumption it won't. As I said above this does not mean that this much is "allocated" or that the system has had to expend many resources doing so.

Solution 4

It's not your program using up that memory, it's the Java VM reserving that memory, regardless of which program is loaded.

Solution 5

This is not the amount of physical memory the application is actually using. A virtual memory used by all processes can be orders of magnitude more than the amount of physical RAM on the machine, without any obvious problems.

Share:
10,783
user3246431
Author by

user3246431

Updated on June 11, 2022

Comments

  • user3246431
    user3246431 about 2 years

    Running a simple Java program on our production machine, I noticed that this program eats up more 10G virt. I know that virtual memory is not that relevant, but at least I would like to understand why this is needed.

    public class Main {
      public static void main(String[] args) {
            System.out.println("Hello World!");
            try {
                    Thread.sleep(10000);
            } catch(InterruptedException e) {
                    /* ignored */
            }
      }
    }
    

    Heres what top is saying when i run that little program:

      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    18764 myuser    20   0 10.2g  20m 8128 S  1.7  0.1   0:00.05 java
    

    Does anyone know why this is happening?

    uname -a says:

    Linux m4fxhpsrm1dg 2.6.32-358.18.1.el6.x86_64 #1 SMP Fri Aug 2 17:04:38 EDT 2013 x86_64 x86_64 x86_64 GNU/Linux
    

    On an older 32bit-linux machine the same program consumes only about 1G virt. The old machine has 4GB RAM, the new one 32GB.

  • Bob
    Bob about 10 years
    Wait. > maximum heap size: Smaller of 1/4th of the physical memory or 1GB - so the default maximum heap is capped at 1 GB. Assuming this hasn't changed, are you saying the initial allocation is higher than the maximum? Because that sounds pretty broken.
  • Luaan
    Luaan about 10 years
    @gnat How so? It creates a contiguous address space for the VM to use, which means that you don't have to fragment the heap seems like a pretty clear reason to me, among others. And I've explained the difference between 32-bit and 64-bit environment.
  • Luaan
    Luaan about 10 years
    @Bob Seems that this applies only to 32-bit Java and pre-1.6 64-bit, on the client VM. Java 1.6+ 64-bit on server VM happily reserves much more.
  • Michael Borgwardt
    Michael Borgwardt about 10 years
    @Bob: "Note: The boundaries and fractions given for the heap size are correct for Java SE 5.0. They are likely to be different in subsequent releases as computers get more powerful."
  • Volker Siegel
    Volker Siegel about 10 years
    No, it's saying it may use that amount, not (yet) using it.
  • thomasrutter
    thomasrutter about 10 years
    Why does this incorrect answer have so many upvotes. The Java VM is not "using" that much memory. It has only allocated that much virtual address space. This has nothing to do with how much "memory" is "used".
  • Roman Starkov
    Roman Starkov about 10 years
    @gnat It does, by explaining that the premise of the question (that 10G of virtual address space is somehow bad or undesirable) is false, and that there is a benefit (protection against fragmentation).
  • Pieter B
    Pieter B about 10 years
    @thomasrutter corrected to say reserve instead of using. This answer is correct because the hello-world program doesn't do anything at all. It's the Java VM that does and the hello-world program gets executed by the VM. That distinction is important and doesn't get made in the question.
  • thomasrutter
    thomasrutter about 10 years
    It's still not correct. It's not "reserving" any memory. It's presenting a virtual address space of a certain size. Memory is not "reserved" or "allocated" at this point. It really is "virtual" address space. It doesn't really reflect actual memory.
  • Patrick Huizinga
    Patrick Huizinga about 10 years
    Not even printing I'd say. More like reserving the right to print 10B continuous labels for a customer.
  • Jules
    Jules about 10 years
    Indeed, thomasrutter is correct: the key distinction isn't between allocated and reserved memory, but between memory and address space, which is a little more abstract.
  • Russell Borogove
    Russell Borogove about 10 years
    Well, you could argue that there's some degree of commitment being done -- e.g. page tables, as other posts have mentioned.
  • Navin
    Navin about 10 years
    @romkyns The question does not presume that 10GB of virtual memory is bad. When you explain why it isn't bad, that's just preaching to the choir. The question is only asking why Java has 10GB as it's default value.