Method to check if an object is finalizable
Reference Counting Method
A reference counter is created with its object,
Its value is increased by one at a time when its object gets one reference.
Its value is decreased by one at a time when its object loses one reference.
Its object becomes a garbage when values of reference counter becomes zero.
But Reference Counting Method is not used by JVM, because it is very difficult to resolve the situation when two objects inter-referenced by each other.
objA.instance = objB
objB.instance = objA
objA=null; objB=null
System.gc()
Root Tracing Method
GC Roots includes the following types:
· Objects referenced by references stored in local variables table of Java Stack
· Objects referenced by static attributes of classes in Method Area (Perm Gen)
· Objects referenced by constants in Constant Pool of Method Area(Perm Gen)
· Object reference by Native Methods (JNI) in Native Stack
GC Chain :
· The chain begins from GC Roots to the ended object.
Reference Types
There are four types of references introduced since JDK1.2, and they are:
Reference Type |
Implementation |
How to get Referent |
GC Condition |
Usage Senario |
Strong Reference |
References like: Object strongRef= new Object() |
Direct Access |
Not Root Traceable |
Commonly Used |
Soft Reference |
java.lang.ref.SoftReference
|
SoftReference.get() |
Before OOM exception is thrown and -XX:SoftRefLRUPolicyMSPerMB |
Memery-Sensitive Cache |
Weak Reference |
java.lang.ref.WeakReference |
WeakRefernce.get() |
Before Next GC |
Canonicalizing mappings(e.g: WeakHashMap) |
Phantom Reference |
java.lang.ref.PhantomReference |
All way return null by PhantomReference.get(), but can get status by ReferenceQueue.poll(). |
Before Next GC |
Get an notification when referent is being recycled. |
F-Queue and finalize()
·If an object is not reachable through any Reference Chain, the object will be marked and checked if its finalize() method can be called.
· If its finalize() method has not been re-written or its finalize() method has alreay been called, the object will not be enqueued into F-Queue;
Ø This object will be finalized by JVM, and its taken memory will be reclaimed.
· Otherwise, this object will be put into F-Queue.
Ø In F-Queue, the finalize() method of this object will be called.
Ø If in its re-written finalize() method, the object connected its self with any object which is in any Reference Chain, it will be Revived, and removed from the F-Queue.
From the diagram, we can understand that:
· For all the objects, finalize() method can only be called once.
· If an object has re-written finalize() method, most of the times, the object would pass through at least two times of GC.
· If an object is finalized(destroyed) by JVM, there is no way it can get back to reachable.
Garbage Collection Algorithms
Mark-Sweep Algorithm
The mark-and-sweep algorithm consists of two phases:
- In the first phase, it finds and marks all accessible objects. The first phase is called the mark phase.
- In the second phase, the garbage collection algorithm scans through the heap and reclaims all the unmarked objects. The second phase is called the sweep phase.
As shown in above graph, before GC Gray Block means unreachable objects, after GC(Mark-Sweep), they are cleaned from heap.
The disadvantage of Mark-Sweep Algorithm:
- low efficency on Sweep stage, normal program execution is suspended while Mark-Sweep process
- Memory of Swept Objects becomes Memory Fragments after GC, heap memory may be too fragmented to allocate memory for big Object or Array.
Mark-Compact Algorithm
The mark-and-compact algorithm consists of two phases:
- In the first phase, it finds and marks all live objects. The first phase is called the mark phase.
- In the second phase, the garbage collection algorithm compacts the heap by moving all the live objects into contiguous memory locations. The second phase is called the compaction phase.
Compared with Mark-Sweep algorithm, The mark-and-compact algorithm avoided the fragments generation after GC, but takes longer time for the defragment work.
Stop-Copy Algorithm
When using the stop-and-copy garbage collection algorithm, the heap is divided into two separate regions. At any point in time, all dynamically allocated object instances reside in only one of the two regions--the active region. The other, inactive region is unoccupied.
When the memory in the active region is exhausted, the program is suspended and the garbage-collection algorithm is invoked. The stop-and-copy algorithm copies all of the live objects from the active region to the inactive region. As each object is copied, all references contained in that object are updated to reflect the new locations of the referenced objects.
After the copying is completed, the active and inactive regions exchange their roles. Since the stop-and-copy algorithm copies only the live objects, the garbage objects are left behind. In effect, the storage occupied by the garbage is reclaimed all at once when the active region becomes inactive.
As the stop-and-copy algorithm copies the live objects from the active region to the inactive region, it stores the objects in contiguous memory locations. Thus, the stop-and-copy algorithm automatically defragments the heap. This is the main advantage of the stop-and-copy approach over the mark-and-sweep algorithm described in the preceding section.
The disadvantage of Stop-and-Copy Algorithm:
Only half of the heap memory can be used all the time.
Generational Collection
Minor Garbage Collections
A minor collection is triggered when Eden becomes full. This is done by copying all the live objects in the new generation to either a survivor space or the tenured space as appropriate. Copying to the tenured space is known as promotion or tenuring. Promotion occurs for objects that are sufficiently old (– XX:MaxTenuringThreshold=<n>), or when the survivor space overflows.
Live objects are objects that are reachable by the application; any other objects cannot be reached and can therefore be considered dead. In a minor collection, the copying of live objects is performed by first following what are known as GC Roots, and iteratively copying anything reachable to the survivor space. GC Roots normally include references from application and JVM-internal static fields, and from thread stack-frames, all of which effectively point to the application’s reachable object graphs.
In generational collection, the GC Roots for the new generation’s reachable object graph also include any references from the old generation to the new generation. These references must also be processed to make sure all reachable objects in the new generation survive the minor collection. Identifying these cross-generational references is achieved by use of a “card table”. The Hotspot card table is an array of bytes in which each byte is used to track the potential existence of cross-generational references in a corresponding 512 byte region of the old generation. As references are stored to the heap, “store barrier” code will mark cards to indicate that a potential reference from the old generation to the new generation may exist in the associated 512 byte heap region. At collection time, the card table is used to scan for such cross-generational references, which effectively represent additional GC Roots into the new generation. Therefore a significant fixed cost of minor collections is directly proportional to the size of the old generation.
There are two survivor spaces in the Hotspot new generation, which alternate in their “to-space” and “from-space” roles. At the beginning of a minor collection, the to-space survivor space is always empty, and acts as a target copy area for the minor collection. The previous minor collection’s target survivor space is part of the from-space, which also includes Eden, where live objects that need to be copied may be found.
The cost of a minor GC collection is usually dominated by the cost of copying objects to the survivor and tenured spaces. Objects that do not survive a minor collection are effectively free to be dealt with. The work done during a minor collection is directly proportional to the number of live objects found, and not to the size of the new generation. The total time spent doing minor collections can be almost be halved each time the Eden size is doubled. Memory can therefore be traded for throughput. A doubling of Eden size will result in an increase in collection time per-collection cycle, but this is relatively small if both the number of objects being promoted and size of the old generation is constant.
Note: In Hotspot minor collections are stop-the-world events. This is rapidly becoming a major issue as our heaps get larger with more live objects. We are already starting to see the need for concurrent collection of the young generation to reach pause-time targets.
Major Garbage Collections
Major collections collect the old generation so that objects can be promoted from the young generation. In most applications, the vast majority of program state ends up in the old generation. The greatest variety of GC algorithms exists for the old generation. Some will compact the whole space when it fills, whereas others will collect concurrently with the application in an effort to prevent it from filling up.
The old generation collector will try to predict when it needs to collect to avoid a promotion failure from the young generation. The collectors track a fill threshold for the old generation and begin collection when this threshold is passed. If this threshold is not sufficient to meet promotion requirements then a “FullGC” is triggered. A FullGC involves promoting all live objects from the young generations followed by a collection and compaction of the old generation. Promotion failure is a very expensive operation as state and promoted objects from this cycle must be unwound so the FullGC event can occur.
Note: To avoid promotion failure you will need to tune the padding that the old generation allows to accommodate promotions (‑XX:PromotedPadding=<n>).
Note: When the Heap needs to grow a FullGC is triggered. These heap-resizing FullGCs can be avoided by setting –Xms and –Xmx to the same value.
Other than a FullGC, a compaction of the old generation is likely to be the largest stop-the-world pause an application will experience. The time for this compaction tends to grow linearly with the number of live objects in the tenured space.
The rate at which the tenured space fills up can sometimes be reduced by increasing the size of the survivor spaces and the age of objects before being promoted to the tenured generation. However, increasing the size of the survivor spaces and object age in Minor collections (–XX:MaxTenuringThreshold=<n>) before promotion can also increase the cost and pause times in the minor collections due to the increased copy cost between survivor spaces on minor collections.
Garbage Collectors Introduction
Serial CollectorThe Serial collector (-XX:+UseSerialGC) is the simplest collector and is a good option for single processor systems. It also has the smallest footprint of any collector. It uses a single thread for both minor and major collections. Objects are allocated in the tenured space using a simple bump the pointer algorithm. Major collections are triggered when the tenured space is full.
Parallel Collector
The Parallel collector comes in two forms. The Parallel collector (‑XX:+UseParallelGC) which uses multiple threads to perform minor collections of the young generation and a single thread for major collections on the old generation. The Parallel Old collector (‑XX:+UseParallelOldGC) , the default since Java 7u4, uses multiple threads for minor collections and multiple threads for major collections. Objects are allocated in the tenured space using a simple bump the pointer algorithm. Major collections are triggered when the tenured space is full.
On multiprocessor systems the Parallel Old collector will give the greatest throughput of any collector. It has no impact on a running application until a collection occurs, and then will collect in parallel using multiple threads using the most efficient algorithm. This makes the Parallel Old collector very suitable for batch applications.
The cost of collecting the old generations is affected by the number of objects to retain to a greater extent than by the size of the heap. Therefore the efficiency of the Parallel Old collector can be increased to achieve greater throughput by providing more memory and accepting larger, but fewer, collection pauses.
Expect the fastest minor collections with this collector because the promotion to tenured space is a simple bump the pointer and copy operation.
For server applications the Parallel Old collector should be the first port-of-call. However if the major collection pauses are more than your application can tolerate then you need to consider employing a concurrent collector that collects the tenured objects concurrently while the application is running.
Note: Expect pauses in the order of one to five seconds per GB of live data on modern hardware while the old generation is compacted.
Note: The parallel collector can sometimes gain performance benefits from -XX:+UseNUMA on multi-socket CPU server applications by allocating Eden memory for threads local to the CPU socket. It is a shame this feature is not available to the other collectors.
Concurrent Mark Sweep (CMS) Collector
The CMS (-XX:+UseConcMarkSweepGC) collector runs in the Old generation collecting tenured objects that are no longer reachable during a major collection. It runs concurrently with the application with the goal of keeping sufficient free space in the old generation so that a promotion failure from the young generation does not occur.
Promotion failure will trigger a FullGC. CMS follows a multistep process:
- Initial Mark : Find GC Roots.
- Concurrent Mark: Mark all reachable objects from the GC Roots.
- Concurrent Pre-clean: Check for object references that have been updated and objects that have been promoted during the concurrent mark phase by remarking.
- Re-mark : Capture object references that have been updated since the Pre-clean stage.
- Concurrent Sweep: Update the free-lists by reclaiming memory occupied by dead objects.
- Concurrent Reset: Reset data structures for next run.
Note: CMS is not a compacting collector, which over time can result in old generation fragmentation. Object promotion can fail because a large object may not fit in the available holes in the old generation. When this happens a “promotion failed” message is logged and a FullGC is triggered to compact the live tenured objects. For such compaction-driven FullGCs, expect pauses to be worse than major collections using the Parallel Old collector because CMS uses only a single thread for compaction.
CMS is mostly concurrent with the application, which has a number of implications. First, CPU time is taken by the collector, thus reducing the CPU available to the application. The amount of time required by CMS grows linearly with the amount of object promotion to the tenured space. Second, for some phases of the concurrent GC cycle, all application threads have to be brought to a safepoint for marking GC Roots and performing a parallel re-mark to check for mutation.
Note: If an application sees significant mutation of tenured objects then the re-mark phase can be significant, at the extremes it may take longer than a full compaction with the Parallel Old collector.
CMS makes FullGC a less frequent event at the expense of reduced throughput, more expensive minor collections, and greater footprint. The reduction in throughput can be anything from 10%-40% compared to the Parallel collector, depending on promotion rate. CMS also requires a 20% greater footprint to accommodate additional data structures and “floating garbage” that can be missed during the concurrent marking that gets carried over to the next cycle.
High promotion rates and resulting fragmentation can sometimes be reduced by increasing the size of both the young and old generation spaces.
Note: CMS can suffer “concurrent mode failures”, which can be seen in the logs, when it fails to collect at a sufficient rate to keep up with promotion. This can be caused when the collection commences too late, which can sometimes be addressed by tuning. But it can also occur when the collection rate cannot keep up with the high promotion rate or with the high object mutation rate of some applications. If the promotion rate, or mutation rate, of the application is too high then your application might require some changes to reduce the promotion pressure. Adding more memory to such a system can sometimes make the situation worse, as CMS would then have more memory to scan.
Garbage First (G1) Collector
G1 (-XX:+UseG1GC) is a new collector introduced in Java 6 and now officially supported as of Java 7u4. It is a partially concurrent collecting algorithm that also tries to compact the tenured space in smaller incremental stop-the-world pauses to try and minimize the FullGC events that plague CMS because of fragmentation. G1 is a generational collector that organizes the heap differently from the other collectors by dividing it into a large number (~2000) of fixed size regions of variable purpose, rather than contiguous regions for the same purpose.
相关推荐
垃圾收集(Garbage Collection, GC)是Java虚拟机的一项重要功能,它负责自动管理内存,识别并回收不再使用的对象,以避免内存泄漏。HotSpot虚拟机提供了多种不同的垃圾收集器,每种都有其特定的性能特性和适用场景...
垃圾回收(Garbage Collection,简称GC)是Java语言的一个重要特性,它自动化地管理程序中的内存分配与释放,避免了传统C++等语言中的内存泄漏问题。本文将围绕Java垃圾回收这一主题,展开一系列关键知识点的详细解析...
【标题】"nginx-upstream-jvm-route-1.15" 涉及的核心知识点是Nginx的upstream模块与JVM路由的整合,特别针对Nginx 1.15版本。这个项目旨在解决在配置Nginx时遇到的特定错误提示“nginx: [emerg] invalid parameter ...
本文档主要关注HotSpot虚拟机的垃圾收集(Garbage Collection, GC)机制的优化,以提高应用程序的性能和稳定性。以下是一些关键知识点: 1. **HotSpot虚拟机**:HotSpot是Oracle JDK中的一个JVM实现,它在运行时...
垃圾回收(Garbage Collection)是 Java 虚拟机(JVM)中的一种机制,旨在自动管理 Java 对象的生命周期,避免内存泄露和溢出。垃圾回收器会周期性地扫描 Java 堆,标记并清除不再使用的对象,从而释放内存空间。 ...
* Concurrent Mark-and-Sweep (CMS) GC:CMS GC 是一种并发标记清除垃圾收集器,主要用于收集 old generation 中的对象。 垃圾收集参数 HotSpot 虚拟机中的垃圾收集参数可以通过命令行选项或 JVM 选项来设置。常见...
《JVM性能调优:深入理解JVM内存模型与优化》 在Java开发中,JVM(Java Virtual Machine)性能调优是提升应用程序效率的关键环节。JVM内存模型的理解和优化,对于解决性能瓶颈、避免内存泄漏以及提高系统稳定性至关...
### JVM调优总结:Xms、Xmx、Xmn、Xss 在Java虚拟机(JVM)的运行过程中,合理的参数配置对于提高程序性能至关重要。本文将对JVM调优中的几个关键参数进行深入解析,包括-Xms、-Xmx、-Xmn和-Xss等,帮助开发者更好...
JVM调优总结 -Xms -Xmx -Xmn -Xss JVM 调优是 Java virtual machine 的性能优化,通过调整 JVM 的参数来提高 Java 应用程序的性能。其中,-Xms、-Xmx、-Xmn、-Xss 是四个重要的参数,分别控制 JVM 的初始堆大小、...
赠送jar包:metrics-jvm-3.1.5.jar; 赠送原API文档:metrics-jvm-3.1.5-javadoc.jar; 赠送源代码:metrics-jvm-3.1.5-sources.jar; 赠送Maven依赖信息文件:metrics-jvm-3.1.5.pom; 包含翻译后的API文档:...
2. `-Xmx`: 这个参数用来设定JVM的最大堆内存大小。它是Java应用能使用的最大内存限制,防止因内存不足导致的`OutofMemoryError`。例如,`-Xmx1024m`表示最大堆内存为1GB。确保`-Xms`小于或等于`-Xmx`,否则JVM无法...
Moonbox(月光宝盒)是JVM-Sandbox生态下的,基于jvm-sandbox-repeater重新开发的一款流量回放平台产品。在jvm-sandbox-repeater基础上提供了更加丰富功能,同时便于线上部署和使用,更多对比参考。 使用场景 你...
垃圾收集(Garbage Collection, GC)是JVM管理内存的重要机制之一。合理的垃圾收集策略可以显著提高应用程序的性能。以下是一些主流的GC算法: 1. **标记-清除(Mark-Sweep)**: - **标记阶段**:标记出所有活动...
代码如下:failed to create jvm error code -4 这一般应是内存不够用所致,解决方法参考如下。 打开 Android Studio 安装目录下的bin目录,查找并打开文件 studio.exe.vmoptions,修改代码: 代码如下:-Xmx512m 为...
JVM调优是优化Java应用程序性能的关键环节,而"jvm-monitor"则提供了一种工具集来帮助开发者监控和分析JVM的状态。本文将深入探讨JVM调优的概念、方法以及如何利用"jvm-monitor"进行有效的监控。 一、JVM调优基础 ...
"JVM Memory View"工具,版本号为0.93.162,就是针对这一需求而设计的JVM调试内存查看器,专为Android Studio用户提供了一个直观、高效的内存分析解决方案。 一、JVM内存概述 Java虚拟机内存主要分为以下几个区域...
jvm知识点整理-脑图
垃圾收集(Garbage Collection, GC)是这一过程的核心,它负责识别并回收不再使用的内存空间。本篇文章将深入探讨几种常见的垃圾收集算法,以及它们在Java J2EE、C#、ASP.NET以及JVM中的应用。 1. **标记-清除...