JAVA garbage collector and memory allocation strategy

introduction

Garbage collection technology is not pioneered by the Java language. Lisp, which was born at MIT in 1960, is the first language that really uses dynamic memory allocation and garbage collection technology. Three issues to consider with garbage collection techniques are:

Which memory needs to be reclaimed?
When?
How?

http://segmentfault.com/a/1190000002931555  talks about the distribution of the java memory runtime area, in which the program counter, virtual machine stack, and local method area are all born with the thread and die with the thread, so these few The area does not need to think too much about recycling. However, the heap and method areas are different. We only know which objects will be created during the running of the program. The allocation and reclamation of this part of the memory are dynamic. It is this part of the memory that the garbage collector is concerned with.

A subject's death criterion

Before the garbage collector collects an object, it must first determine whether the object is still possible to be used in the program. The necessary and sufficient condition is that there is no reference accessible by the program to point to the object instance . The easiest way is to add a reference counter to the object instance addition. Whenever there is a reference to it, the counter is incremented by one. When the reference is invalid, the counter is decremented by one. If the counter value is 0, it means that there is no reference to it. , can be recycled. However, it is not a necessary condition for the counter to be 0 in this method. For example, if two object instances are generated, and the attributes of each object instance point to each other, then the two object instances each have at least one reference.

What java uses is 可达性分析算法to find some objects as "GC Roots"nodes, and start searching downward from these nodes. When an object reaches the "GC Roots" node 没有可达路径, it means that this object is unavailable. Nodes that are "GC Roots" in java include:

  1. Objects referenced in the virtual machine stack,

  1. The object referenced by the static property of the method area,

  2. The object referenced by the method area constant,

  3. The object referenced by the native call in the native method area.

161641_uW2m_1983603.png

reference expansion

如果reference类型的数据中存储的数值是另一块内存的起始地址,那么这块内存就代表着一个引用。一个对象在这种状态下,只能有被引用和没有被引用两种状态。java对引用概念进行了扩充,将引用分为强引用(new),软引用(softReference),弱引用(WeakReference),虚引用(PhantomReference)。如果强引用存在,则垃圾收集器不会回收该对象。如果系统即将发生内存溢出异常,那么垃圾回收集器则会回收软引用对象。弱引用对象只能存活到下一次垃圾收集之前。虚引用对象不会对其生存时间构成任何影响。

对象的自我救赎

在垃圾收集器发现某一个对象到"GC Roots"路径不可达时,先会判断该对象是否覆盖finalize()方法,或是否执行过finalize()方法。如果覆盖了且没有执行过该方法,则会将该对象放到低优先级的Finalizer线程队列中去执行finalize()方法,如果在finalize()方法中该对象又被引用,则会有一次逃脱被回收的命运。

方法区的回收

方法区中主要回收废弃的常量和无用的类。对于常量,如果没有引用指向常量,则该常量会被回收。对于类的回收则麻烦许多,首先要判断该类是无用的类无用的类要满足三个条件:

  1. 所有类的实例被回收。

  2. 加载该类的ClassLoader已经被回收。

  3. Class没有被引用,不会通过反射访问该类的方法。

二 垃圾回收算法

标记-清除算法(Mark-Sweep)

该算法分为两个阶段:首先标记处要回收的对象,标记完成后统一回收所有被标记的对象。
存在的问题:

  1. 标记和清除效率都不高

  2. 标记清除后会产生大量内存碎片,分配大对象时可能触发另一次垃圾收集。

162639_lRPR_1983603.png

复制算法(Copying)

该算法将内存分为两个等大小的区域,每次只使用一个区域。当一个区域快用完了,就将这个区域中存活的对象复制到另一个区域。

优点是避免了内存碎片的产生,缺点是浪费内存空间。

162929_kGQX_1983603.png

有公司研究表明,新生代的对象98%都是朝生暮死,所以虚拟机把新生代内存划分为一个较大的Eden空间和两个较小的Survivor空间。每次只是用Eden空间和一个Survior空间,当进行复制清理时,将Survivor空间和Eden空间中存活的对象复制到另一块Survivor空间。当Survivor空间不够用时,就会依赖老年代进行分配担保。

标记-整理算法(Mark-Compact)

针对老年代对象存活率高的情况,复制算法明显不合适,于是采用标记整理算法,标记和标记清除算法相同,二后边的整理则是让所有存活的对象都向一端移动,然后清理掉边界外的内存。

163309_pPkR_1983603.png

分代收集

当前虚拟机都采用分代收集,分代的依据是对象的存活周期。一般新生代存活率低,采用复制算法。老年代存活率高采用标记整理标记清除

一般来讲,新生代空间会小很多,具体比例一般要看应用场景。而默认的大小一般是老年代的1/4到1/3。

三 垃圾收集器

114752_Cpuf_1983603.jpg
由于虚拟机采用了分代收集,所以针对不同代收集器也不同。上图是HotSpot虚拟机的垃圾收集器,连线表示可以协同工作。

Serial收集器,复制算法,它是一个单线程的收集器,并且在进行收集时会暂停其他线程,它默认是client模式下的新生代收集器。

ParNew收集器是Serial收集器的多线程版,它是第一款并发收集器。

Parallel Scavenge收集器可以精确控制吞吐量(用户代码运行时间/(用户代码时间+垃圾收集时间))

SerialOld收集器是serial收集器的老年版,采用标记整理算法,同样是单线程收集器。

ParallelOld是ParallelScavenge收集器的老年版,使用多线程和标记整理算法。

CMS收集器是以最短回收停顿时间为目标的收集器,采用标记清除算法,在重视响应速度的系统中得以应用。但是缺点是对CPU资源敏感,无法处理浮动垃圾,易产生内存碎片。

G1收集器It is the latest collector, which can be applied to JDK1.7u4 and above. It divides the memory into multiple regions, and the new generation and the old generation respectively contain multiple regions. G1 tracks each Region, judges the value of garbage, and recycles the Region with the largest value first.

Safe point

The concept of a safe point means that when a GC is performed, the worker thread should be stopped, and it will be easier to judge whether the object is alive or not. And stopping the thread should be at a safe moment, so there will be a concept of a safe point.

There are two ways to suspend a thread. The first is to force the suspension. If some threads do not reach the safe point, let them run to the safe point, which is called 抢先式中断. The second is to add a conditional judgment at the safe point during the compilation process to determine whether the 0x160100 memory page is readable. If it is not readable, it will be suspended. This is called 主动式中断.

Four memory allocation and recycling strategies

163144_0sxV_1983603.png
The allocation of objects is allocated on the heap. The objects are mainly allocated in the Eden area of ​​the new generation. If the local thread allocation buffer is started, it will be allocated in the TLAB according to the thread priority. In a few cases, it is also possible to directly assign to the old generation.

When objects are allocated in the Eden area, when there is not enough space in the Eden area, the virtual machine initiates a new generation garbage collection.

If objects require a lot of contiguous memory space, such as String types and arrays. Large objects are bad news for virtual machine memory allocation, and dying large objects are terrible news. Frequent occurrences of large objects can lead to multiple triggers of garbage collection. For such objects, parameters can be set to store large objects directly into the old age.

Each object has an age counter. When the object is born in the Eden area, the counter is incremented by one every time it passes through a GC and is stored in the Survivor. When the age increases to a certain level (default 15), it will be stored in the old age. At the same time, if objects of the same age in the Survivor space occupy more than 50% of the space, it will also directly enter the old age.

Summarize

Garbage Collection Algorithms: 复制算法, 标记-清除算法, 标记-清理算法.

Garbage collector features: Copy for the young generation, mark-to-clean for the old generation, and mark-to-clean for the CMS.

The default ratio between the size of the Eden space and the size of the Survivor space is 8:1, that is, 10% of the space in the new generation is used to store the copied objects.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326137475&siteId=291194637