JVM - Yash-777/LearnJava GitHub Wiki

Run-Time Data Areas

The Java Virtual Machine defines various run-time data areas that are used during execution of a program. Some of these data areas are created on Java Virtual Machine start-up and are destroyed only when the Java Virtual Machine exits. Other data areas are per thread. Per-thread data areas are created when a thread is created and destroyed when the thread exits.

Image Reference

JVM Architecture – Understanding JVM Internals Reference

JNI Types and Data Structures

Java Language and Virtual Machine Specifications

The Java VM manages two kinds of memory: heap and non-heap memory, both of which are created when the Java VM starts.

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.

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.

The Java HotSpot VM defines two generations: the young generation (sometimes called the "nursery") and the old generation. The young generation consists of an "Eden space" and two "survivor spaces." The VM initially assigns all objects to the Eden space, and most objects die there. When it performs a minor GC, the VM moves any remaining objects from the Eden space to one of the survivor spaces. The VM moves objects that live long enough in the survivor spaces to the "tenured" space in the old generation. When the tenured generation fills up, there is a full GC that is often much slower because it involves all live objects. The permanent generation holds all the reflective data of the virtual machine itself, such as class and method objects.

Young Generation Collection Using the Serial Collector memory management whitepaper

The operation of a young generation collection using the serial collector. The live objects in Eden are copied to the initially empty survivor space, labeled To in the figure, except for ones that are too large to fit comfortably in the To space. Such objects are directly copied to the old generation. The live objects in the occupied survivor space (labeled From) that are still relatively young are also copied to the other survivor space, while objects that are relatively old are copied to the old generation.

The Java HotSpot VM uses a generational garbage collector, a well-known technique that exploits the following two observations:

  • Most allocated objects will die young.
  • Few references from older to younger objects exist.

OutOfMemoryError: PermGen Space

Permanent generation has been completely removed in JDK 8. From Bug Enhancement classes metadata is now stored in the native heap and this space is called Metaspace.StackPost, blogs.oracle.com

Java < 8 Java 8
Image from JConsole Image from docs.oracle.com

In other words, the combined size of the eden and survivor spaces will be one fourth of the total heap size.

Typical Heap Printout from JDK8

Heap
  PSYoungGen      total 10752K, used 4419K
    [0xffffffff6ac00000, 0xffffffff6b800000, 0xffffffff6b800000)
    eden space 9216K, 47% used
      [0xffffffff6ac00000,0xffffffff6b050d68,0xffffffff6b500000)
    from space 1536K, 0% used
      [0xffffffff6b680000,0xffffffff6b680000,0xffffffff6b800000)
    to   space 1536K, 0% used
      [0xffffffff6b500000,0xffffffff6b500000,0xffffffff6b680000)
  ParOldGen       total 20480K, used 20011K
      [0xffffffff69800000, 0xffffffff6ac00000, 0xffffffff6ac00000)
    object space 20480K, 97% used 
      [0xffffffff69800000,0xffffffff6ab8add8,0xffffffff6ac00000)
  Metaspace       used 2425K, capacity 4498K, committed 4864K, reserved 1056768K
    class space   used 262K, capacity 386K, committed 512K, reserved 1048576K

Parallel Compaction

Parallel compaction complements the existing parallel collector by performing full GCs in parallel to take advantage of multiprocessor (or multi-threaded) hardware. As the name suggests, it is best suited to platforms that have two or more CPUs or two or more hardware threads. It was first made available in JDK 5.0 update 6; the implementation in JDK 6 contains significant performance improvements.


Runnable Interface Thread Class
Single Object can be used for multiple threads For every thread new object has to be created
Threads Concept
- Object Thread Safe
     - Field (Volatile)
     - Member Function (Synchronized)

To coordinate shared data access among multiple threads, the Java virtual machine associates a lock with each object and class. A lock is like a privilege that only one thread can "possess" at any one time. If a thread wants to lock a particular object or class, it asks the JVM. At some point after the thread asks the JVM for a lock -- maybe very soon, maybe later, possibly never -- the JVM gives the lock to the thread. When the thread no longer needs the lock, it returns it to the JVM. If another thread has requested the same lock, the JVM passes the lock to that thread.

Class locks are actually implemented as object locks. When the JVM loads a class file, it creates an instance of class java.lang.Class. When you lock a class, you are actually locking that class's Class object.

Threads need not obtain a lock to access instance or class variables. If a thread does obtain a lock, however, no other thread can access the locked data until the thread that owns the lock releases it.

⚠️ **GitHub.com Fallback** ⚠️