GC算法与四种引用有哪些

发布时间:2021-10-12 14:43:25 作者:iii
来源:亿速云 阅读:173

本篇内容介绍了“GC算法与四种引用有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

GC算法

常见的GC算法包括:

 引用计数法

实现原理:

缺点:

由于引用计数法上述的缺点,Java中并未采用作为GC算法。

 标记清除法

标记清除法将垃圾回收分为两个阶段:

标记阶段:

GC算法与四种引用有哪些

清除后:

GC算法与四种引用有哪些

缺点很明显,就是回收后的空间是不连续的,工作效率会低于连续的内存空间。

 复制算法

核心思想:

优点是回收后的内存空间是没有碎片的,而缺点是如果存在大量的对象,需要花费大量的时间复制,并且内存只有原来的一半。

比如下图中的A、B两块相同的内存空间,A在垃圾回收的时候,将存活对象复制到B中,B在复制后保持连续:

GC算法与四种引用有哪些

复制完成后,A会被清空,并将B设置为当前使用的空间。

Java的新生代串行垃圾回收器中,使用了复制算法,新生代分为eden区、from区以及to区。其中fromto区是两块内存相同的空间,也叫survivor区,也就是幸存者空间。在垃圾回收的时候,eden区以及from区存活的对象会被复制到to区,然后清空from区与eden区,接着fromto区的角色将会交换,也就是下一次垃圾回收的时候,会从原来的to区(新的from区)复制到原来的from区(新的to区)。

 标记压缩法

标记压缩法是一种老年代算法,在标记清除法的基础上做了一些优化,和标记清除法一样,首先也需要从根节点开始,对所有可达对象做一次标记,然后将所有存活对象压缩到内存的一端,接着清理边界外的所有空间,图示如下:

GC算法与四种引用有哪些

标记压缩法的优点是可以避免碎片的产生,又不需要两块相同的内存空间。

 分代算法

分代算法并不是一种具体的垃圾回收算法,分代算法其实是一种根据每块内存空间的特点使用不同回收算法以提高效率的算法。比如:

 分区算法

分区算法将整个堆空间划分成连续的不同小区间,每个小区间都独立使用,独立回收,如图所示:

GC算法与四种引用有哪些3 四种引用

Java里面提供了4个级别的引用:

下面分别来看一下。

 强引用

强引用就是代码中一般使用的引用类型,强引用的对象是可触及的,不会被回收,比如:

StringBuffer str = new StringBuffer("a");

如果上面的代码运行在方法体内,那么局部变量str会被分配在栈上,而对象StringBuffer实例会被分配在堆上,str指向的是StringBuffer实例所在的堆空间,通过str可以操作该实例,str就是StringBuffer实例的强引用。

又比如执行了以下代码:

StringBuffer str1 = str;

那么str1也会指向str指向的对象,也就是它们都指向同一个StringBuffer实例,此时str1==str的值为真,因为两个指向的是同一个堆空间地址。

强引用的特点如下:

 软引用

软引用是被强引用弱一点的引用类型,如果一个对象只持有软引用,那么当堆空间不足的时候,就会被回收,软引用可以使用SoftReference类实现,比如下面的代码:

public static void main(String[] args){
    Byte[] b = new Byte[1024*1024*8];
    SoftReference<Byte[]> softReference = new SoftReference<>(b);
    b = null;
    System.out.println(softReference.get());
    System.gc();
    System.out.println("After GC");
    System.out.println(softReference.get());
    b = new Byte[1024*1024*8];
    System.gc();
    System.out.println(softReference.get());
}

OpenJDK 11.0.10上,加上-Xmx40m的输出如下:

[Ljava.lang.Byte;@1fbc7afb
After GC
[Ljava.lang.Byte;@1fbc7afb
null

可以看到,当垃圾回收的时候,未必会回收软引用对象,但当内存紧张时,会回收软引用对象。

 弱引用

弱引用是比软引用弱的引用类型,在垃圾回收的时候,只要发现弱引用,不管系统空间使用情况如何,都会将对象进行回收。但是由于垃圾回收器的线程通常优先级不高,并不一定能很快发现弱引用对象,这种情况下弱引用对象可以存在较长时间。弱引用例子如下:

public static void main(String[] args){
    Byte[] b = new Byte[1024*1024*8];
    WeakReference<Byte[]> softReference = new WeakReference<>(b);
    b = null;
    System.out.println(softReference.get());
    System.gc();
    System.out.println("After GC");
    System.out.println(softReference.get());
}

输出(-Xmx40m):

[Ljava.lang.Byte;@1fbc7afb
After GC
null

可以看到在GC后,弱引用对象会被立即回收。

软引用、弱引用的一个常见使用场景是保存可有可无的缓存数据,当系统内存不足时,这些内存数据会被回收,不会导致OOM,而内存充足时,这些缓存数据又可以存在相当长的时间,从而起到让系统加速的作用。

 虚引用

虚引用是所有引用类型中最弱的一个,一个持有虚引用的对象和没有引用几乎是一样的,随时都可能被垃圾回收器回收。另外,试图使用虚引用的get()方法获取强引用的时候,总是会失败,并且虚引用需要和引用队列一起使用,作用在与跟踪垃圾回收过程。

public static void main(String[] args) throws Exception {
    ReferenceQueue<String> queue = new ReferenceQueue<>();
    PhantomReference<String> reference = new PhantomReference<>(new String("test"),queue);
    System.out.println(reference.get());
}

输出结果:

null

“GC算法与四种引用有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

推荐阅读:
  1. JVM的四种GC算法分别是什么
  2. JVM虚拟机四种引用及GC实践方法是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

bash java

上一篇:shopex同步ucenter的redirect导致script不运行怎么办

下一篇:2021最新版的memcache面试题有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》