主页 > 市场 > JAVA垃圾回收
2018年

JAVA垃圾回收

JAVA垃圾收受接收

光阴:20180307

问题:

若何鉴定工具为垃圾工具

引用计数法

可达性阐发法

若何收受接收

收受接收策略

标记-清除

复制算法

标记-收拾算法

分代网络算法

垃圾收受接收器

Serial

Parnew

Cms

G1

何时收受接收

引用计数法

很多教科书给出如下定义:给工具添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用掉效时,计数器值就减1;任何时候计数器为0的工具便是弗成能再被应用的。

然则,至少主流的JAVA虚拟机里面没有选用引用计数法来治理内存,此中最主要的缘故原由便是它很难办理工具之间的轮回引用的问题。

打印具体的GC日志信息参数(VM arguments):

-verbose:gc

-XX:+PrintGCDetails

测试堆中多个工具之间存在轮回引用,外部没有引用,垃圾收受接收环境:

public class Main {

public Object instance = null;

public static void main(String[] args) {

Main m1 = new Main();

Main m2 = new Main();

m1.instance = m2;

m2.instance = m1;

m1 = null;

m2 = null;

System.gc();

}

}

结果:

[GC (System.gc()) [PSYoungGen: 1996K->936K(38400K)] 1996K->944K(125952K), 0.0012261 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 936K->0K(38400K)] [ParOldGen: 8K->565K(87552K)] 944K->565K(125952K), [Metaspace: 2735K->2735K(1056768K)], 0.0054020 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

Heap

PSYoungGentotal 38400K, used 333K [0x00000000d5900000, 0x00000000d8380000, 0x0000000100000000)

eden space 33280K, 1% used [0x00000000d5900000,0x00000000d59534a8,0x00000000d7980000)

from space 5120K, 0% used [0x00000000d7980000,0x00000000d7980000,0x00000000d7e80000)tospace 5120K, 0% used [0x00000000d7e80000,0x00000000d7e80000,0x00000000d8380000)

ParOldGentotal 87552K, used 565K [0x0000000080a00000, 0x0000000085f80000, 0x00000000d5900000)

object space 87552K, 0% used [0x0000000080a00000,0x0000000080a8d770,0x0000000085f80000)

Metaspaceused 2741K, capacity 4486K, committed 4864K, reserved 1056768K

class spaceused 304K, capacity 386K, committed 512K, reserved 1048576K

public class Main {

public Object instance = null;

public Main() {

byte [] m = new byte[20 * 1024 * 1024];

}

public static void main(String[] args) {

Main m1 = new Main();

Main m2 = new Main();

m1.instance = m2;

m2.instance = m1;

m1 = null;

m2 = null;

System.gc();

}

}

结果:

[GC (System.gc()) [PSYoungGen: 22476K->872K(38400K)] 42956K->21360K(125952K), 0.0010626 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 872K->0K(38400K)] [ParOldGen: 20488K->565K(87552K)] 21360K->565K(125952K), [Metaspace: 2735K->2735K(1056768K)], 0.0052890 secs] [Times: user=0.14 sys=0.00, real=0.00 secs]

Heap

PSYoungGentotal 38400K, used 333K [0x00000000d5900000, 0x00000000d8380000, 0x0000000100000000)

eden space 33280K, 1% used [0x00000000d5900000,0x00000000d59534a8,0x00000000d7980000)

from space 5120K, 0% used [0x00000000d7980000,0x00000000d7980000,0x00000000d7e80000)

tospace 5120K, 0% used [0x00000000d7e80000,0x00000000d7e80000,0x00000000d8380000)

ParOldGentotal 87552K, used 565K [0x0000000080a00000, 0x0000000085f80000, 0x00000000d5900000)

object space 87552K, 0% used [0x0000000080a00000,0x0000000080a8d770,0x0000000085f80000)

Metaspaceused 2741K, capacity 4486K, committed 4864K, reserved 1056768K

class spaceused 304K, capacity 386K, committed 512K, reserved 1048576K

图解:

引用计数法垃圾收受接收验证

可达性阐发算法

这个算法的基础思路便是经由过程一系列的称为“GC Roots”的工具作为动身点,从这个节点开始向下搜索,搜索走过的路径称为引用链,当一个工具到GC Roots没有任何引用链时,则证实此工具是弗成用的。便是从GCRoots到这个工具是弗成达的。

可作为G'C'Roots的工具

虚拟机栈(局部变量表)

措施区的类静态属性所引用的工具

措施区中常量所引用的工具

本地措施栈中引用的工具

垃圾网络算法

标记-清楚算法

最根基的网络算法是“标记-清除(Mark-Sweep)”算法,犹如它的名字一样,算法分为“标记”和"清除"两个阶段:首先标记出所有必要收受接收的工具,在标记后统一收受接收所有被标记的工具。标记历程便是(可达性阐发算法)。

不够之处

1.效率问题:标记和清除两个历程的效率都不高。

2.空间问题:标记清除后会孕育发生大年夜量不继续的内存碎片,空间碎片太多可能会导致今后在法度榜样运行历程中必要分配较大年夜工具时,无法找到足够的继续内存而不得不提前触发另一次垃圾网络动作。

复制算法

复制算法:它将可用内存按容量划分为大年夜小相等的风凉,每次只应用此中的一块,当这一块的内存用完了,就将还存活的工具复制到另一块上面,然后再把已应用过的内存空间一次清理掉落。

1.新生代

Eden 伊甸园

Survivor 存活区

Tenured Gen

2.老年代

标记 -收拾算法

标记-收拾算法有可以叫做标记-收拾-清除算法。此中标记历程仍旧与“标记-清除”算法一样,但后续步骤不是直接对可收受接收工具进行清理,而是让所有存活的工具都向一端移动,然后直接清理掉落端界限以外的内存(被标记必要清除的工具)。

复制网络算法在工具存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,假如不想挥霍50%的空间,就必要有额外的空间进行分配保证,已应对被应用的内存中工具都100%存活的极度环境,以是在老年代一样平常不能直接用这种算法。

分代网络算法

当前商业虚拟机的垃圾网络都采纳“分代网络Generational Collection算法”,只是根据工具存活的周期的不合将内存划分为几块。一样平常把JAVA堆分为新生代和老年代。这样就可以根据各个年代的特搜寻纳最得当的网络算法。在新生代中,每次垃圾网络时都发明有大年夜批工具逝世去,只有少量存活,那就应用复制算法,只必要付出少量存活工具的复制资源就可以完成网络。而老年代中由于工具存活率高、没有额外的空间对它进行分配保证,就必须应用“标记-清理”或者“标记-收拾”算法来进行收受接收。