Java - ttulka/programming GitHub Wiki

  • java -XX:+PrintFlagsFinal prints all the flags available
  • jinfo -flag <flag> <pid> shows actual value of the flag for the process
  • jps prints all java running processes

Java Memory

  • Every thread has its own stack.
  • Stack stores only primitives.
  • Complex objects are stored on the heap.
  • There is only one heap shared across all threads.
  • Pointers to objects in the heap are stored on the stack.
  • Primitives are passed to a method as a copy, objects as a reference.
  • -Xmx4g or -XX:MaxHeapSize=4g sets the maximum heap size capacity
  • -Xms6m or -XX:InitialHeapSize=6m sets the initial heap size capacity
  • Metaspace contains general metadata and serves as a stack for static variables.

Stack

Each thread has its own stack that holds a frame for each method executing on that thread.

  • Last In First Out (LIFO) data structure, so the currently executing method is at the top of the stack.
  • The frame is removed (popped) when the method returns normally or if an uncaught exception is thrown

Each frame contains:

  • local variable array,
  • return value,
  • operand stack
  • reference to runtime constant pool for class of the current method

Local Variables Array contains all the variables used during the execution of the method, including a reference to this, all method parameters and other locally defined variables.

  • boolean, byte, char, long, short, int, float, double
  • reference (point to objects or arrays on the heap)
  • returnAddress

All types take a single slot in the local variable array except long and double which both take two consecutive slots because these types are double width (64-bit instead of 32-bit).

Heap

Heap is used to allocate class instances and arrays at runtime.

  • Arrays and objects can never be stored on the stack because a frame is not designed to change in size after it has been created.
  • Objects stored on the heap are not removed when a method ends. Instead, only by the garbage collector.

To support garbage collection the heap is divided into three sections:

  • Young Generation
    • Often split between Eden and Survivor
  • Old Generation (also called Tenured Generation)
  • Permanent Generation

Non-Heap Memory

Objects that are logically considered as part of the JVM mechanics are not created on the Heap.

  • Permanent Generation that contains
    • the method area
    • interned strings
  • Code Cache used for compilation and storage of methods that have been compiled to native code by the JIT compiler

Garbage Collection

Any objects which is not reachable through a reference from the stack is eligible for garbage collection.

Types of collector:

  • Serial -XX:+UseSerialGC one-threaded, stops processing
  • Parallel -XX:+UseParallelGC multi-threaded, minimizes processing paused (default Java 8)
  • Mostly Concurent
    • -XX:+UseConcMarkSweeepGC (default Java 9)
    • Garbage First (G1) -XX:+UseG1GC (default Java 10)
      • -XX:ConcGCThreads=N
      • -XX:InitiatingHeapOccupancyPercent=N
  • Low-latency
    • Z Garbage Collector -XX:+UseZGC -XX:+UnlockExperimentalVMOptions
      • designed to work well with huge amounts of memory
      • available on 64-bit Linux.
  • Passive or "no-op"
    • Epsilon GC -XX:+UseEpsilonGC -XX:+UnlockExperimentalVMOptions
      • useful for measuring and managing application performance
      • removes the impact GC has on performance
      • handles memory allocation but doesn't recycle it when objects are no longer used
      • allow the application to run out of memory and crash

Weak, Soft, and Phantom References

  • Strong References (default) are not eligible for garbage collection.
  • Soft references try to keep the reference.
    • cleared at the discretion of the garbage collector in response to memory demand
    • used to implement memory-sensitive caches
    • guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError
  • Weak references don’t try to keep the reference.
    • used to implement canonicalizing mappings (of only reachable instances)
    • used in WeakHashMap
  • Phantom references don’t free the reference until cleared.
    • eligible for garbage collection, but, before removing them from the memory, JVM puts them in a queue called ‘reference queue’
    • used for scheduling pre-mortem cleanup actions, improve the finalization process.
    • used to determine when an object was removed from the memory
      • For example, we can wait for a large object to be removed before loading another one.

Memory leaks

  • Soft Leak - no longer needed objects remains referenced
  • Heap Dump - file containing info about the heap at any moment of time
    • -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=path/to/file
    • jmap -dump:live,format=b,file=heap.bin <pid> creates a heap dump file
    • Java heap analyzer: Memory Analyzer (MAT) https://www.eclipse.org/mat

Just In Time compilation (JIT)

JVM compiles snippets of frequently run byte code into native code.

  • code runs faster the longer it is left to run
  • doesn't stop running (while compiled, JVM uses the interpreted version)
  • -XX:+PrintCompilation prints information about JIT compilation

JIT uses two different compilers for different levels (1-4)

  • C1 compiler does first three levels of compilation
  • C2 compiler does the fourth level of compilation (most frequent runs, the best performance)
  • -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation creates a log file about compilation

Code cache is used by JIT

  • XX:+PrintCodeCacheprints information about the code cache
  • Code cache can be changed by:
    • XX:InitialCodeCacheSize
    • XX:ReservedCodeCacheSize
    • XX:CodeCacheExpansionSize
  • Could be monitored by jconsole: Memory > Memory Pool "Code Cache"
    • Uses extra cache for the communication JVM<->jconsole
    • Windows:
      1. make sure /Users/<user>/AppData/Local/Temp/hsperfdata_<user> is writable for Everyone (Security tab)
      2. env var TMP must be different from TEMP, set TMP to eg. c:\tmp

JVM 64bit can run with either client and server compiler.

  • Use the -client compiler for short-time apps with a quick startup
    • avoids overheads of JIT compilation
    • only if heap < 3GB
  • Use the -server compiler for long-live apps
    • might be faster with long and double
    • necessary for heap > 4GB

Collections

Java Collections

References

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