- 📙 Optimizing Java: Practical Techniques for Improving JVM Application Performance (440 pages)
- 🎥 A Comprehensive Introduction to Java Virtual Machine (JVM) (~4 hours, Udemy)
- 🎥 Memory footprint of a Java process by Andrei Pangin (YouTube)
- How JVM Works – JVM Architecture? (GeeksForGeeks)
- Understanding Java Compilation: From Bytecodes to Machine Code in the JVM (Azul blog series)
- Class Loaders in Java (Baeldung)
- Memory footprint of the JVM (Spring blog)
- Java using much more memory than heap size (Stack Overflow)
- Stack Memory and Heap Space (Baeldung)
- Deep Dive Into the New Java JIT (Baeldung)
- What are some of the most useful JVM JIT optimizations and how to use them? (OverOps)
- Developers disassemble! Use Java and hsdis to see it all. (Oracle blog)
- source code (
.java) --> bytecode (.class) --> JVM interpreter + JIT for hot methods - JVM supports 256 opcodes (202 in use)
- early - at compile time
- for static methods and all fields
invokestatic
- late - at runtime
- for instance methods
invokevirtual
- dynamic (at runtime)
- handled by a class loader (typically from a file or URL)
- read
.classfile into memory - create
Classobject on the heap - lazy - only once the class is really used
- new instance
- static method call
- static field access except for compile time constants (e.g.
static final XXX = 5;) - subtype is loaded (i.e. superclasses are loaded before subclasses)
- reflection
- verify bytecode
- final classes not subclassed, final method not overridden
- bytecode integrity, jump instructions
- allocate memory for static variables, initialize with default values
- resolve symbolic links with real values (dynamic linking)
- constant pool
- assign static variables
- execute static blocks
- bootstrap
- parent of all classloaders
- loads Java standard library (core) and other class loaders
JAVA_HOME/jre/lib
- written in native code
ArrayList.class.getClassLoader();returns null which means bootstrap
- extension
- loads libs from
JAVA_HOME/jre/lib/ext
- loads libs from
- application (system)
- loads "our" classes (i.e. from classpath,
-cp)
- loads "our" classes (i.e. from classpath,
- user-defined class loaders
- loading from outside the classpath
- application class loader asks the extension CL which in turn asks the bootstrap CL
- top CLs are considered most trustworthy
- bootstrap CL doesn't perform security checks
- uniqueness, isolation and visibility
- heap, non-heap memory, direct memory (ByteBuffer), native libraries (JNI)
- see Native Memory Tracking
- regular objects, arrays, class objects
jcmdhas some useful commands,pmapfor ultimate memory analysis- metaspace
- use
-XX:MaxMetaspaceSizeto put upper limit (unbounded by default) - methods
- constant pools
- symbols
- annotations
- compressed class space - for < 32 GB heaps
- information about the classes that have been loaded
- use
- threads
- memory used by threads (stack frames - method calls, local variables, method params)
- use
Xssto size stack frames (default 1 MB - allocated lazily)
- code cache - JIT compilation
- GC - garbage collector - remembered sets, mark bitmap
- symbol
- symbol table - field names, method signatures
- string pool - interned strings
jcmd PID VM.stringtable
- internal -
Unsafe.allocateMemory
- used to be in PermGen, from Java 8 it's metaspace (located on native heap)
- not limited by heap size (as it used to be in Java 7 and older)
- mostly under compressed class space
- metadata
- reference to class object
- runtime constant pool (under symbol)
- field info
- method info + bytecode
- method table
- interpret bytecode instruction by instruction
- templated - at JVM start, the interpreter builds an optimized code for each opcode based on the exact architecture
- slow
- basic unit is method
- collects runtime data - allows to make highly efficient optimization
- PGO - profile guided optimization
- tiered compilation
- C1 - client - faster but less optimized code, after ~ 1,500 method invocations
- C2 - server - slower but better optimized code, after ~ 10,000 method invocations
- modern VMs combine both C1 & C2 (tiered compilation)
- branch prediction
- method inlining
- loop unrolling
- object escape analysis
- null check elimination
- tracks each and every object available in the JVM heap space and removes unused ones (mark & sweep)
- GC roots
- local variables
- static variables
- active threads
- JNI references
- GC roots
- generational hypothesis - most objects either die young or live for a long time
- young (eden, survivor 1 & 2) vs. old space
- young - minor GC
- both - full GC
- tradeoffs
- latency
- throughput
- footprint
- replacement for the CMS collector (deprecated)
- designed for applications running on multiprocessor machines with large memory space
- balanced tradeoffs
- parallel, concurrent, incrementally compacting
- main tuning knob
-XX:MaxGCPauseMillis
- scalable low-latency (sub-millisecond) garbage collector (worse throughput than G1)
- performs all expensive work concurrently, without stopping the execution of application threads for more than 10 ms
invokevirtualto call normal class methodsinvokestaticto call static methodsinvokeinterfaceto call interface methodsinvokespecialto call constructors or private methodsinvokedynamic(aka Indy, since JDK 7) to support efficient and flexible execution of method invocations in the absence of static type information
