How Is the Java Memory Pool Divided

How is the java memory pool divided?

Heap memory

The heap memory is the runtime data area from which the Java VM allocates memory for all class instances and arrays. The heap may be of a fixed or variable size. The garbage collector is an automatic memory management system that reclaims heap memory for objects.

  • Eden Space: The pool from which memory is initially allocated for most objects.

  • Survivor Space: The pool containing objects that have survived the garbage collection of the Eden space.

  • Tenured Generation or Old Gen: The pool containing objects that have existed for some time in the survivor space.

Non-heap memory

Non-heap memory includes a method area shared among all threads and memory required for the internal processing or optimization for the Java VM. It stores per-class structures such as a runtime constant pool, field and method data, and the code for methods and constructors. The method area is logically part of the heap but, depending on the implementation, a Java VM may not garbage collect or compact it. Like the heap memory, the method area may be of a fixed or variable size. The memory for the method area does not need to be contiguous.

  • Permanent Generation: The pool containing all the reflective data of the virtual machine itself, such as class and method objects. With Java VMs that use class data sharing, this generation is divided into read-only and read-write areas.

  • Code Cache: The HotSpot Java VM also includes a code cache, containing memory that is used for compilation and storage of native code.

Here's some documentation on how to use Jconsole.

In Java Memory Pool what is the replacement of Code Cache replacement in JAVA 11?

I believe the restructuring came with Java 9.

Instead of having a single code heap, the code cache was segmented into distinct code heaps, each of which contains compiled code of a particular type. Such a design enables to separate code with different properties.

The main idea was to improve performance and enable future extensions.

There are three different top-level types of compiled code:

  • JVM internal (non-method) code
  • Profiled-code
  • Non-profiled code

The corresponding code heaps are:

  • A non-method code heap containing non-method code, such as compiler buffers and bytecode interpreter. This code type will stay in the code cache forever.

  • A profiled code heap containing lightly optimized, profiled methods with a short lifetime.

  • A non-profiled code heap containing fully optimized, non-profiled methods with a potentially long lifetime.

You can find some useful details (like motivation to this restructuring, how to configure new heaps, etc.) in JEP-197 :)

What is the difference between Java Non Heap Memory and Stack Memory? Are they Same if not what is the difference between them?

There are essentially three categories of storage in all C-based languages (and most other languages):

  1. Heap
  2. Stack
  3. Static (with several variations)

Heap you're familiar with.

Stack you're also familiar with, but you just don't know it. When you have a method with "local" variables, those variables are allocated in a "invocation frame". The "invocation frame" is allocated when you call the method and deleted when you return from the method, and hence it's most efficiently implemented using a "stack" that grows with call and shrinks with return.

Static is stuff that you don't explicitly allocate and essentially exists from the time program execution begins.

The space required for stack is generally fairly small and is lumped in with "Non Heap Memory" in the categories above.

Memory details of JVM as a process

Native Memory Tracking (NMT) feature of Java 8 helps to answer your questions.

Run Java with the option -XX:NativeMemoryTracking=summary
Then at run time execute the following command to print JVM memory statistics:

jcmd <pid> VM.native_memory summary

The output will look like:

Total:  reserved=664192KB,  committed=253120KB

- Java Heap (reserved=516096KB, committed=204800KB)
(mmap: reserved=516096KB, committed=204800KB)

- Class (reserved=6568KB, committed=4140KB)
(classes #665)
(malloc=424KB, #1000)
(mmap: reserved=6144KB, committed=3716KB)

- Thread (reserved=6868KB, committed=6868KB)
(thread #15)
(stack: reserved=6780KB, committed=6780KB)
(malloc=27KB, #66)
(arena=61KB, #30)

- Code (reserved=102414KB, committed=6314KB)
(malloc=2574KB, #74316)
(mmap: reserved=99840KB, committed=3740KB)

- GC (reserved=26154KB, committed=24938KB)
(malloc=486KB, #110)
(mmap: reserved=25668KB, committed=24452KB)

- Compiler (reserved=106KB, committed=106KB)
(malloc=7KB, #90)
(arena=99KB, #3)

- Internal (reserved=586KB, committed=554KB)
(malloc=554KB, #1677)
(mmap: reserved=32KB, committed=0KB)

- Symbol (reserved=906KB, committed=906KB)
(malloc=514KB, #2736)
(arena=392KB, #1)

- Memory Tracking (reserved=3184KB, committed=3184KB)
(malloc=3184KB, #300)

- Pooled Free Chunks (reserved=1276KB, committed=1276KB)
(malloc=1276KB)

- Unknown (reserved=33KB, committed=33KB)
(arena=33KB, #1)

More information here and here.

Java heap terminology: young, old and permanent generations?

This seems like a common misunderstanding. In Oracle's JVM, the permanent generation is not part of the heap. It's a separate space for class definitions and related data. In Java 6 and earlier, interned strings were also stored in the permanent generation. In Java 7, interned strings are stored in the main object heap.

Here is a good post on permanent generation.

I like the descriptions given for each space in Oracle's guide on JConsole:

For the HotSpot Java VM, the memory
pools for serial garbage collection
are the following.

  • Eden Space (heap): The pool from which memory is initially allocated
    for most objects.
  • Survivor Space (heap): The pool containing objects that have survived
    the garbage collection of the Eden
    space.
  • Tenured Generation (heap): The pool containing objects that have existed
    for some time in the survivor space.
  • Permanent Generation (non-heap): The pool containing all the reflective
    data of the virtual machine itself,
    such as class and method objects. With
    Java VMs that use class data sharing,
    this generation is divided into
    read-only and read-write areas.
  • Code Cache (non-heap): The HotSpot Java VM also includes a code cache,
    containing memory that is used for
    compilation and storage of native
    code.

Java uses generational garbage collection. This means that if you have an object foo (which is an instance of some class), the more garbage collection events it survives (if there are still references to it), the further it gets promoted. It starts in the young generation (which itself is divided into multiple spaces - Eden and Survivor) and would eventually end up in the tenured generation if it survived long enough.

Tomcat Server Status Memory Pool

Those names are different memory areas used by Java Virtual Machine and its Garbage Collector.

The memory model used by JVM differs from one version to another and from one vendor to another. When looking for information you have to know what version of Java you are running.

See e.g. "Understanding the Java Memory Model and Garbage Collection" article from DZone.

Tomcat just displays the names returned by Java via its instrumentation API (java.lang.management.ManagementFactory.getMemoryPoolMXBeans()).

JVM Memory Types

From java documentation link :

A MemoryUsage object represents a snapshot of memory usage. Instances of the MemoryUsage class are usually constructed by methods that are used to obtain memory usage information about individual memory pool of the Java virtual machine or the heap or non-heap memory of the Java virtual machine as a whole.

A MemoryUsage object contains four values:

init represents the initial amount of memory (in bytes) that the Java virtual machine requests from the operating system for memory management during startup.

used represents the amount of memory currently used (in bytes).

committed represents the amount of memory (in bytes) that is guaranteed to be available for use by the Java virtual machine. The amount of committed memory may change over time (increase or decrease).

max represents the maximum amount of memory (in bytes) that can be used for memory management. Its value may be undefined. The maximum amount of memory may change over time if defined.

The amount of used and committed memory will always be less than or equal to max if max is defined.

A memory allocation may fail if it attempts to increase the used memory such that used > committed even if used <= max would still be true (for example, when the system is low on virtual memory).

Have a look at this link to understand about various API related to memory.

Have a look at this SE question for Heap and Non Heap memory types and internals of them.

How is the java memory pool divided?

I have not found any information about CollUsed and I am suspecting a type error in the question. I suspect that it may be committed memory if I am not wrong.

Please cross check once on exact API.

When does Java calls Garbage Collector

The answer to the first question is: it depends. You can set different GC strategies and you can probably even convince the JVM to not run the GC until the heap is full but it's generally not a good idea. And it definitely isn't what typically happens, instead the heap is divided into several smaller areas of varying purpose and GC is triggered by their filling up.

To answer the second question: no, that's a completely different issue.

With -Xms256m the JVM will ask the operating system for 256 megabytes of memory on startup.

If it runs out of it, it will ask for more until it reaches the amount specified by -Xmx. Asking the OS to allocate your process more memory takes time and therefore is best avoided on a server, where you can predict almost exactly how much memory will be available for your application.

Note that the above process is only indirectly related to the GC, which only clears heap that's already been assigned to the JVM by the OS.

Edit: To check what exactly is going on, you can start your JVM with the -verbose:gc command line option.



Related Topics



Leave a reply



Submit