- What: Free up space by removing dead/unused objects in the memory heap and avoid memory leaks
- Each GC triggers stop-the-world events
- The larger the memory = The longer the stop-the-world time
- JVM Heap memory is physically divided into 2 parts - Young and Old Generation
- Purpose: All new objects are created
- Garbage collection: Minor GC
- Consist: Eden memory and two survivor memory spaces
- Implications:
- Since there are only short-lived objects, Minor GC is very fast and application is not affected
- Process:
- Most newly created objects are located in eden memory space
- When eden space is filled, minor gc is performed and all survivor objects are moved to one of the survivor spaces
- Minor GC also checks the survivor objects and move to the other survivor space; thus at a time, one survivor is always empty
- Objects that survived many GC cycles are moved to Old generation
- Usually done by setting a threshold for age of young generation objects
- Purpose: Objects that are long-lived and survived many rounds of Minor GC
- Garbage collection: Major GC
- Implications:
- All application threads are stopped until GC operation completes, i.e. application will be
unresponsive for the GC duration
- Thus, if there's a responsive application, when major GC is ongoing, will notice a lot of timeout errors
- Takes a long time as the GC checks all the live objects
- Duration depends on GC strategy
- All application threads are stopped until GC operation completes, i.e. application will be
unresponsive for the GC duration
- Purpose: Application metadata required by the JVM to describe the classes and methods used
- Not part of Java Heap memory
- Populated by JVM at runtime based on classes used
- Also contains Java SE library classes and methods
- Garbage collection: Objects are garbage collected in a full garbage collection
- Purpose: Store class structure (runtime constants and static variables), code for methods and
constructors
- Runtime constant pool: per-class runtime representation of constant pool in a class
- Created by JVM memory managers to create a pool of immutable objects
- E.g.: String pool
- Can belong to Heap or Permanent Generation, depending on JVM memory manager implementation
| VM Switch | VM Switch Description |
|---|---|
| -Xms | Initial heap size when JVM starts |
| -Xmx | Maximum heap size |
| -Xmn | Size of young generation, rest to Old Generation |
| -XX:PermGen | Initial size of Perm Gen memory |
| -XX:MaxPermGen | Maximum Perm Gen size |
| -XX:SurvivorRatio | Ratio of eden space and survivor space Default value = 8, i.e. 80% is eden space and 10% for each survivor space |
| -XX:NewRatio | Ratio of old and new generation sizes Default value = 2 |
- Java has automatic garbage collection which involves 3 steps:
- Marking: identifies which objects are in use and not in use
- Normal deletion: GC removes unused objects and reclaim the free space to be allocated to other objects
- Deletion with compacting: For better performance, after deleting unused objects, all the survived
objects can be moved to be togher
- This will increase the performance of allocation of memory to newer objects
- There are 2 problems with a simple mark and delete approach:
- Not efficient because most of the newly created objects will become unused
- Objects that are in-use for multiple garbage collection cycle are most likely to be in-use for future cycles
- Hence, the generational garbage collection is meant to overcome the shortcomings
- Eden -> S0 -> S1 -> Old Gen
- Survivor spaces exist to reduce the number of objects sent to the old generation and thus
reduces the occurrence of major GC
- Also because although many objects cannot be deleted after a minor GC, they do not live long
- Survivor spaces exist to reduce the number of objects sent to the old generation and thus
reduces the occurrence of major GC
- Garbage collection will occur on objects that tare not reachable
- When are objects considered not reachable?
- As long as the application can reach these objects via the GC roots, they are considered reachable and will not be garbage collected
- GC roots are always reachable (referenced by the JVM)
- Simplified: a local variable of reference type that will always point to an object in the heap (provided it is not null)
- When are objects considered not reachable?
- 4 kinds of GC roots:
- Local variables
- Kept alive by thread stack
- Active java threads
- Static variables and constants
- Classes themselves can be Gc-ed which will remove all referenced static variables
- JNI references (java objects that the native code has created as part of JNI call)
- Local variables
- By default, Java 9 onwards uses Garbage-first (G1) collector
- Concurrent collector that optimizes throughput and latency
- Application is thus not stopped
- Upon startup, the JVM sets the region size (1MB to 32MB depending on heap size) where the eden, survivor, and old generations are logical sets of thetse regions and are not contiguous
- There are multiple ways to monitor the memory usage and garbage collection activity
jstat: JVM statistics- See Oracle jstat
- Application logs
-Xloggc:/tmp/gc.log: information about GC at each collection-XX:HeapDumpPath=/tmp/my-heap-dump.hprof: heap dump
See Oracle Throughput and Footprint Measurement
- Default JVM options and values
- Run
java -XX:+PrintFlagsFinal -versionto see the available VM flags and default values - Run
jinfo -flags <pid>to see the full command that was executed for running process
- Run
- VisualVM
- VisualVM heapdump:
/private/var/folders/...
- VisualVM heapdump:
- Jconsole
- Part of JDK
See Oracle Java 8 OOM Exception
- When garbage collection happened
- How often GC is happening in the JVM
- How much memory is being collected each time
- How long GC is running for in the JVM
- Percentage of time spent by JVM for garbage collection
- What type of garbage collection happened - minor or full GC?
- JVM heap and non-heap memory usage
- CPU utilization of the JVM
- If the baseline heap usage is consistently increasing after each garbage collection, it may
indicate:
- Application's memory requirements are growing
- Memory leak (i.e. application is neglecting release references to objects that are no longer needed, unintentionally preventing them from getting garbage collected)
- It should stay flat under normal circumstances
- If there is an unexpected increase in this metric, it could signal:
- Java application is creating long-lived objects
- Creating more humongous objects (they automatically get allocated to regions in the old generation)
- Java (JVM) Memory Model
- G1 Garbage Collector
- Java Memory Management
- How does Garbage Collection work
- Java SE 17 standard options for java
- How to read GC activity logs
https://trello.com/c/PG9SVsf2/158-java-memory-sharing-4-hours
- How to deal with humongous objects?
- "In-order to reduce copying overhead, the Humongous objects are not included in any evacuation pause. A full garbage collection cycle compacts Humongous objects in place." - source
- Flyweight
- "Humongous objects need contiguous space -> thus need help to prevent because may exit if cannot find enough contiguous space"
- Mine: Some people recommend to increase the region size so that objects do not automatically fall under humongous objects
- https://devblogs.microsoft.com/java/whats-the-deal-with-humongous-objects-in-java/
- WRITE: What are the tools that I have used to help troubleshoot memory issues?
- [?] How the prometheus metrics could have helped
jvm_gc_seconds.maxminorGCG1 Evacuation PhaseG1 Humongous Allocation
- Learning
- Indexing
- Memory management
- Monitoring
- Pros
- Cons
- Industrial examples
- Debug tools
- Typical causes of high memory usage
- How to identify memory leak
- After thoughts
- Size of objects
- Flame graph
- async-profiler vs java profiler recorder
- Affected flags:
-XX:InitiatingHeapOccupancyPercent- For changing marking threshold
-XX:G1MixedGCLiveThresholdPercentand-XX:G1HeapWastePercent- To change mixed garbage collections decisions
-XX:G1MixedGCCountTargetand-XX:G1OldCSetRegionThresholdPercent- When want to adjust CSet for old regions (C set is collection set - i.e. a set of regions that should be collected in the next cycle)
XX:G1MixedGCLiveThresholdPercent- For changing the threshold which determines whether a region should be added to the CSet or not
- Only regions whose live data percentage are less than the threshold will be added to the CSet
- The higher the threshold, the more likely a region will be added to the CSet, i.e. more mixed GC evacuation and longer evacuation time will happen
- Old regions with most garbage is chose for
- For changing the threshold which determines whether a region should be added to the CSet or not
-XX:G1HeapWastePercent- Amount of reclaimable space, expressed as a % of the heap size that G1 will stop doing mixed GC's
- If the amount of space that can be reclaimed from old generation regions compared to the total heap is less than this, G1 will stop mixed GCs