Understanding JVM Memory Allocation and Java Out of Memory: Heap Space

44,034

Solution 1

How does the JVM actually allocate memory for itself?

For the heap it allocate one large continuous region of memory of the maximum size. Initially this is virtual memory however, over time it becomes real memory for the portions which are used, under control of the OS

How does this relate to how the OS communicates available memory to the JVM?

The JVM has no idea about free memory in the OS.

Or more generally, how does memory allocation for any process actually work?

In general it uses malloc and free.

How does virtual memory come into play?

Initially virtual memory is allocated and this turns into real memory as used. This is normal for any process.

Let's say you have a system with 32GB of physical memory and you allocate all 32GB to your Java process.

You can't. The OS need some memory and there will be memory for other purposes. Even within the JVM the heap is only a portion of the memory used. If you have 32 GB of memory I suggest as 24 GB heap max.

Let's say that your process actually consumes all 32GB of memory,

Say you have 48 GB and you start a process which uses 32 GB of main memory.

how can we enforce the process to use virtual memory instead of running into OOM exceptions?

The application uses virtual memory right from the start. You cannot make the heap too large because if it starts swapping your machine (not just your application) will become unusable.

You can use more memory than you have physical by using off heap memory, carefully. However managed memory must be in physical memory so if you need a 32 GB heap, buy 64 GB of main memory.

Solution 2

The JVM (or for that matter any process) that wants to allocate memory will call the C runtime 'malloc' function. This function maintains the heap memory of the C runtime. It, in turn, obtains memory from the operating system kernel - the function used for this is platform dependent; in Linux it could be using the brk or sbrk system calls.

Once the memory has been obtained by the JVM, it manages the memory itself, allocating parts of it to the various objects created by the running program.

Virtual memory is handled entirely by the operating system kernel. The kernel manages mapping of physical memory pages to the address space of various processes; if there is less physical memory than is needed by all the processes in the system then the OS Kernel will swap some of it out to disk.

You can't (and don't need to) force processes to use Virtual Memory. It is transparent to your process.

If you are getting 'out of memory' errors, then the causes are likely to be:

  1. The JVM limits are being exceeded. These are controlled by various command line arguments and/or properties as you stated in your question

  2. The OS may have run out of swap space (or not have any swap space configured to start with). Or some OSs don't even support virtual memory, in which case you have run out of real memory.

  3. Most OSs have facilities for the administrator to limit the amount of memory consumed by a process - for example, in Linux the setrlimit system call and/or the ulimit shell command, both of which set limits that the kernel will observe. If a process requests more memory than is allowed by the limits, then the attempt will fail (typically this results in an out of memory message).

Solution 3

This blog looks at Java memory utilisation which you might find useful:

http://www.waratek.com/blog/november-2013/introduction-to-real-world-jvm-memory-utilisation

Solution 4

  1. The JVM allocates Java heap memory from the OS and then manages the heap for the Java application. When an application creates a new object, the JVM sub-allocates a contiguous area of heap memory to store it. An object in the heap that is referenced by any other object is "live," and remains in the heap as long as it continues to be referenced. Objects that are no longer referenced are garbage and can be cleared out of the heap to reclaim the space they occupy. The JVM performs a garbage collection (GC) to remove these objects, reorganizing the objects remaining in the heap.
    Source: http://pubs.vmware.com/vfabric52/index.jsp?topic=/com.vmware.vfabric.em4j.1.2/em4j/conf-heap-management.html

  2. In a system using virtual memory, the physical memory is divided into equally-sized pages. The memory addressed by a process is also divided into logical pages of the same size. When a process references a memory address, the memory manager fetches from disk the page that includes the referenced address, and places it in a vacant physical page in the RAM.

Source: http://searchstorage.techtarget.com/definition/virtual-memory

Share:
44,034

Related videos on Youtube

HiChews123
Author by

HiChews123

Updated on November 26, 2020

Comments

  • HiChews123
    HiChews123 over 3 years

    I'm looking into really understanding how memory allocation works in the JVM. I'm writing an application in which I'm getting Out of Memory: Heap Space exceptions.

    I understand that I can pass in VM arguments such as Xms and Xmx to up the heap space that the JVM allocates for the running process. This is one possible solution to the problem, or I can inspect my code for memory leaks and fix the issue there.

    My questions are:

    1) How does the JVM actually allocate memory for itself? How does this relate to how the OS communicates available memory to the JVM? Or more generally, how does memory allocation for any process actually work?

    2) How does virtual memory come into play? Let's say you have a system with 32GB of physical memory and you allocate all 32GB to your Java process. Let's say that your process actually consumes all 32GB of memory, how can we enforce the process to use virtual memory instead of running into OOM exceptions?

    Thanks.

    • Kyle
      Kyle over 10 years
      If you haven't used a profiler yet, like VisualVM, do it. It will give you lots of insight as to what is happening inside your application, such as which objects are not being garbage collected and when memory is being allocated.
  • Tushar Pandey
    Tushar Pandey about 10 years
    Question : can you please tell me , why JVM_outOfMemory is a error not exception .
  • Vishy
    Vishy about 10 years
    @TusharPandey From the Javadoc 8 for Error An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. You wouldn't want catch(Exception e) to catch such errors.
  • Jonatas Emidio
    Jonatas Emidio over 5 years
    Unfortunately this link is not available anymore :(
  • ealeon
    ealeon over 5 years
    in 32GB physical mem, you can specify JVM to use 32GB since it is virtual memory in the beginning, right? ie java program will still start? and it will only throw an error if it actually tries to use that much memory?
  • Vishy
    Vishy over 5 years
    @ealeon it reserves the memory up front, so it depends on the OS whether it allows this.
  • ealeon
    ealeon over 5 years
    @PeterLawrey i was told that's not the case stackoverflow.com/questions/54318518/…
  • Vishy
    Vishy over 5 years
    @ealeon Linux/Unix/MacOS allocate memory lazily, on demand, unless you use the JVM command line option to preallocate the memory. You can create a JVM whose size exceeds main memory + swap. On Windows, it allocates the memory eagerly and will prevent a process from creating JVM it couldn't give the memory/swap to immediately.