JAVA的GC(garbage collection)

是Java虚拟机进行垃圾回收的主要场所,其次要场所是方法区。
jvm堆内存分为如下几个部分:

图片.png

和GC相关的JVM优化
1.创建的对象会优先在Eden分配,如果是大对象(很长的字符串数组)则可以直接进入老年代。虚拟机提供一个-XX:PretenureSizeThreadhold参数,令大于这个参数值的对象直接在老年代中分配,避免在Eden区和两个Survivor区发生大量的内存拷贝。
2.长期存活的对象将进入老年代,每一次MinorGC(年轻代GC),对象年龄就大一岁,默认15岁晋升到老年代,通过
-XX:MaxTenuringThreshold设置晋升年龄。

Minor GC(年轻代GC):对象优先在Eden中分配,当Eden中没有足够空间时,虚拟机将发生一次Minor GC,因为Java大多数对象都是朝生夕灭,所以Minor GC非常频繁,而且速度也很快。Full GC(老年代GC):Full GC是指发生在老年代的GC,当老年代没有足够的空间时即发生Full GC,发生Full GC一般都会有一次Minor GC。

为什么要有Survivor区?
为什么需要Survivor空间。我们看看如果没有 Survivor 空间的话,垃圾收集将会怎样进行:一遍新生代 gc 过后,不管三七二十一,活着的对象全部进入老年代,即便它在接下来的几次 gc 过程中极有可能被回收掉。这样的话老年代很快被填满, Full GC 的频率大大增加

JVM如何判定一个对象是否应该被回收?
判断一个对象是否应该被回收,主要是看其是否还有引用。判断对象是否存在引用关系的方法包括引用计数法以及可达性分析

引用计数法:是一种比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只需要收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。****可达性分析:可达性分析的基本思路就是通过一系列可以做为root的对象作为起始点,从这些节点开始向下搜索。当一个对象到root节点没有任何引用链接时,则证明此对象是可以被回收的。以下对象会被认为是root对象:栈内存中引用的对象方法区中静态引用和常量引用指向的对象被启动类(bootstrap加载器)加载的类和创建的对象Native方法中JNI引用的对象。

Java堆分为新生代和老年代,采用了不同的回收方式.

垃圾回收算法
HotSpot 虚拟机采用了可达性分析来进行内存回收,常见的回收算法有标记-清除算法,复制算法和标记整理算法。
标记-清除算法(Mark-Sweep):

标记-清除算法执行分两阶段。

第一阶段:从引用根节点开始标记所有被引用的对象,

第二阶段:遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,并且会产生内存碎片。
缺点:

执行效率不稳定,会因为对象数量增长,效率变低标记清除后会有大量的不连续的内存碎片,空间碎片太多就会导致无法分配较大对象,无法找到足够大的连续内存,而发生gc

垃圾回收器
JVM中的垃圾收集器主要包括7种,即Serial,Serial Old,ParNew,Parallel Scavenge,Parallel Old以及CMS,G1收集器。
CMS
CMS收集器是一种以获取最短回收停顿时间为目标的收集器。CMS收集器是基于标记-清除算法实现的,是一种老年代收集器,通常与ParNew一起使用。CMS的垃圾收集过程分为4步:初始标记:需要“Stop the World”,初始标记仅仅只是标记一下GC Root能直接关联到的对象,速度很快。并发标记:是主要标记过程,这个标记过程是和用户线程并发执行的。重新标记:需要“Stop the World”,为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(停顿时间比初始标记长,但比并发标记短得多)。并发清除:和用户线程并发执行的,基于标记结果来清理对象。

G1:

你可能感兴趣的:(JAVA的GC(garbage collection))