Java Heap Memory management is one of the main factors affecting performance.
Heap memory overflow is a very common failure of Java projects, and you must understand how the Java heap memory works before you can solve the problem.
Let's look at how the Java heap memory is divided,
- The JVM memory is divided into heap memory and non-heap memory, and heap memory is divided into the younger generation (young Generation), the older generation (old Generation), and the non-heap memory for a permanent generation (Permanent Generation).
- The young generation is also divided into Eden and Survivor District. The Survivor District is composed of Fromspace and Tospace. The Eden area accounts for a large capacity, survivor two zones, and the default ratio is 8:1:1.
- Heap memory Usage: The object is stored, and the garbage collector collects these objects and then recycles them according to the GC algorithm.
- Non-heap memory usage: A permanent generation, also known as a method area, that stores objects that are long-lived when the program runs, such as metadata, methods, constants, attributes, and so on for a class.
In the JDK1.8 version obsolete permanent generation, instead of the meta-space (metaspace), meta-space and the permanent generation of similar, are the implementation of the method area, their biggest difference is: the meta-space is not in the JVM, but the use of local memory.
There are two parameters to note in meta-space:
- Metaspacesize: Initialization of the meta-space size, controlling the occurrence of GC thresholds
- Maxmetaspacesize: Limit the maximum size of the meta space to prevent an exception from consuming excessive physical memory
Why remove a permanent generation?
Removal of the permanent generation reason: changes made to fuse the hotspot JVM with the JRockit VM (new JVM Technology) because JRockit does not have a permanent generation.
With meta-space there is no longer a permanent oom problem!
Concept of generational
The newly generated object is first placed in the Young generation Eden area, when the Eden space is full, triggering the minor GC, the surviving object moves to the Survivor0 area, the SURVIVOR0 zone is full, and the minor gc,survivor0 zone survivor is moved to the Suvivor1 area. , which ensures that there is always an empty survivor area for a period of time. After several minor GC still surviving objects moved to the old age.
The old age of storing long-lived objects, which would trigger major gc=full GC,GC during a full time, will stop all threads waiting for GC to complete, so for applications with high response requirements minimize the occurrence of major GC and avoid response timeouts.
Minor GC: Clean up the young generation
Major GC: Clean up the permanent generation
Full GC: Cleans up entire heap space, including young and permanent generations
All GCs will stop applying all threads.
Why generational?
The objects are classified according to survival probability, and the long-lived objects are placed in the fixed area, thus reducing the scanning garbage time and GC frequency. Different garbage collection algorithms are used for classification, and the algorithm is more and more disadvantages.
Why is survivor divided into two equal-sized surviving spaces?
Mainly in order to solve fragmentation. If the memory fragmentation is serious, that is, two objects occupy discontinuous memory, the existing continuous memory is not enough to store new objects, it will trigger the GC.
JVM Heap Memory Common parameters
Parameters |
Description |
-xms |
Heap memory initial size, unit m, G |
-XMX (Maxheapsize) |
Heap memory maximum allowable size, generally not greater than 80% of physical memory |
-xx:permsize |
Non-heap memory initial size, general application settings initialize 200m, Max 1024m is enough |
-xx:maxpermsize |
Maximum allowable size for non-heap memory |
-xx:newsize (-XNS) |
Young generation Memory Initial size |
-xx:maxnewsize (-XMN) |
Young generation memory maximum allowable size, also can be abbreviated |
-xx:survivorratio=8 |
The capacity ratio of the Eden and survivor districts in the young generation, which defaults to 8, or 8:1 |
-xss |
Stack memory size |
Garbage collection algorithm (Gc,garbage Collection)
Red is the marked Inactive object, and green is the active object.
- Mark-Clear (Mark-sweep)
The GC is divided into two stages, marked and cleared. All recyclable objects are marked first, and all tagged objects are reclaimed uniformly after the tag is complete. Discontinuous memory fragmentation is also generated. Too many fragments can cause a large object to be allocated at a later time when the program is running and cannot find enough contiguous memory to trigger the GC again.
- Replication (copy)
Divide the memory by capacity by two blocks, using only one piece at a time. When this piece of memory is used up, the surviving object is copied to another piece, and then the used memory space is cleaned out once. This makes it possible to recycle half the memory area each time, and not to consider the memory fragmentation problem, which is simple and efficient. The disadvantage requires twice times more memory space.
- Labeling-Finishing (mark-compact)
It is also divided into two stages, first marking the objects that can be recycled, then moving the surviving objects to one end and then clearing out the memory outside the boundary. This method avoids the fragmentation of the tag-cleanup algorithm, and avoids the spatial problem of the replication algorithm.
In the general young generation after the GC, there will be a small number of objects to survive, you will choose the replication algorithm, as long as a small amount of survival object replication costs can be completed collection. In older years, because of the high survival rate of objects and the lack of extra memory space allocations, it is necessary to use the tag-cleanup or tag-collation algorithm for recycling.
Garbage collector
- Serial Collector (Serial)
Compare the old collector, single thread. When collecting, you must pause the applied worker thread until the collection is finished.
- Parallel collector (Parallel)
Multiple garbage collection threads work in parallel, are more efficient on multicore CPUs, and application threads are still waiting.
- CMS collector (Concurrent Mark Sweep)
The CMS collector is designed to shorten the pause application time and is based on the mark-and-sweep algorithm implementation, which is divided into 4 steps, including:
- Initial mark (Initial Mark)
- Concurrent tagging (Concurrent mark)
- Re-tagging (Remark)
- Concurrent Purge (Concurrent Sweep)
Where the initial tag, re-tagging both steps still need to pause the application thread. The initial tag simply marks the object that the GC roots can directly relate to, is fast, the concurrent tagging stage is the token recyclable object, and the re-tagging phase is to fix the tag record of the part of the object that the tag has changed during the concurrency tag, because the user program continues to work. This phase pause time is slightly longer than the initial marker phase, but is much more than the concurrent tagging time period.
Because the most expensive concurrency token and the concurrent cleanup process of the collector thread can work with the user thread throughout the process, the CMS Collector memory collection is executed concurrently with the user, greatly reducing the pause time.
- G1 collector (Garbage first)
The G1 collector divides the heap memory into separate regions of equal size (region) and can predict the pause time, which can predict the reason that it avoids a full-scale collection of the entire heap. G1 tracks the value of garbage accumulation in each region (the amount of space available and the time it takes to reclaim), maintains a prioritized list in the background, and prioritizes the region with the highest value per time, based on the allowable collection times, guaranteeing a higher collection efficiency over a limited period of time.
The work of the G1 collector consists of 4 steps, including:
- Initial mark (Initial Mark)
- Concurrent tagging (Concurrent mark)
- End Mark (final mark)
- Filter collection (Live Data counting and evacuation)
The initial tag, like the CMS, marks the object that the GC roots can directly relate to. The concurrency token marks the surviving object from the GC root, which takes a long time, but can also be executed concurrently with the application thread. The final tag is also intended to fix the part of the tag record that is causing the markup to change as the user program continues to function during concurrent tagging. Finally, the recovery value and cost of each region are sorted in the filter recovery phase, and the recovery is performed according to the expected GC pause time.
Garbage collector parameters
Parameters |
Description |
-xx:+useserialgc |
Serial collector |
-xx:+useparallelgc |
Parallel collector |
-xx:+useparallelgcthreads=8 |
Number of parallel collector threads, and how many threads are garbage collected, typically equal to the number of CPUs |
-xx:+useparalleloldgc |
Specify the old age for parallel collection |
-xx:+useconcmarksweepgc |
CMS collector (Concurrent collector) |
-xx:+usecmscompactatfullcollection |
Enable memory space compression and collation to prevent excessive memory fragmentation |
-xx:cmsfullgcsbeforecompaction=0 |
Represents how many times the full GC begins to compress and defragment, and 0 means that compression and grooming are performed immediately after each full GC |
-xx:cmsinitiatingoccupancyfraction=80% |
Indicates that the old memory space uses 80% when the CMS collection is started to prevent excessive full GC |
-xx:+useg1gc |
G1 Collector |
-xx:maxtenuringthreshold=0 |
In the young generation after a few GC survived, entered the old age, 0 said directly into the old age |
Why is heap memory overflow?
Objects that survived the GC after the young generation were copied into the old age. When there is insufficient space in the old age, the JVM will perform a full GC for the old age. If the GC is still unable to store objects copied from the Survivor area, an oom (out of Memory) will appear.
There are several reasons why the OOM (out of Memory) anomaly is common:
1) Old age memory shortage: java.lang.OutOfMemoryError:Javaheapspace
2) Insufficient memory for permanent generation: Java.lang.OutOfMemoryError:PermGenspace
3) code bug, memory can not be collected in time.
Oom can occur in these memory areas, and when you actually encounter Oom, you can locate the memory overflow in which area according to the exception information.
You can add a parameter-xx:+heapdumponoutmemoryerror to let the virtual machine dump the current memory heap dump snapshot for post-mortem analysis when a memory overflow exception occurs.
Familiar with the Java Memory Management mechanism and configuration parameters, the following is the Java application Startup options tuning configuration:
JAVA_OPTS="-server -Xms512m -Xmx2g -Xmn1g -XX:PermSize=256m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+UseParallelGCThreads=8 XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:-PrintGC -XX:-PrintGCDetails -XX:-PrintGCTimeStamps -Xloggc:../logs/gc.log"
- Set minimum and maximum heap memory, maximum reference historical utilization settings
- Set up GC garbage collector for CMS or G1
- Enable GC logging for post-analysis
Summary
- Selecting an efficient GC algorithm effectively reduces the time to stop application threads.
- Frequent full GC increases the pause time and CPU usage, can increase the old age space size to reduce the full GC, but will increase the payback time, according to the business appropriate trade-offs.
It's not an egg, it's a technical dry
In the 2018/2019 years Docker/kubernetes container technology is undoubtedly the hottest technology in the industry. According to the recruitment profile, container technology has become an operational engineer, architect the necessary skills.
To help you quickly grasp the mainstream technology, less detours, improve the core competitiveness. decided to write "based on the Kubernetes enterprise container cloud Platform landing and practice," the article column, to friends in the enterprise floor container cloud platform to provide some enterprise practical guidance, I hope that what they learn to think can help everyone, can be inspired.
What this column can reap
- Master Docker, Kubernetes core Concepts
- Familiar with Docker daily operation and maintenance management
- Skilled deployment of kubernetes clusters
- Familiar with daily operation and maintenance management of container cloud Platform
- Container Cloud Platform architecture design and planning
- Migrating microservices Business architectures to container cloud platforms
Article Column Portal: "Landing and practice of container cloud platform based on Kubernetes Enterprise"
Java heap memory is overflowing again! Teach you a trick to kill.