Java垃圾搜集算法和垃圾回收算法

垃圾回收主要针对的是JVM的堆内存,分为新生代和老年代。

按照以前的叫法,还有一个永久代,它在方法区里保存了class信息、静态变量、常量池等。

从jdk-1.8开始,方法区的实现发生了一些变化,取消了永久代的概念,多出了一个叫做元空间的概念。
在内存上独立了出来,跟老年代不再是物理上连续的,直接使用了JVM的内存。

这样会使得内存溢出的可能性进一步减小,空间大小变得更容易扩展。
与此同时,方法区也将一部分数据转移了出去,比如类的静态变量、字符串常量池等都放到了堆内存当中。这个变化从1.8后正式开始。

我们平时所讨论的JVM,都是Hopspot版本。刚才提到的永久代,是Hopspot特有的。

在堆内存中,从垃圾回收的范围上说,一般分为两种,新生代的垃圾回收叫Young GC,老年代的垃圾回收通常伴随着新生代的垃圾回收,叫做Full GC。

对垃圾的处理分为搜集算法和回收算法。

垃圾搜集算法

首先需要标记出需要回收的对象,也就是要确定哪些是垃圾。有两种方法,一种叫引用计数法,另一种叫做可达性分析算法。

引用计数法
每个对象都会有一个引用计数器,每当有一个引用指向这个对象的时候,对象的计数器就+1,这样的话,只要观察这个对象的引用计数器,数值>0,就表示还有人在使用,这个对象就不能回收。

当引用计数器=0时,表示没有任何引用指向这个对象,该对象已经不可访问,那么垃圾搜集器就可以回收它。

引用计数法的缺点:如果有两个对象都是垃圾,但它们之间相互引用,引用计数器就永远不可能为0。

可达性分析算法
因此,Java使用了一种叫做可达性分析的算法,就是从整个堆内存的根对象出发,看看有多少对象是可达的,有多少是不可达的,无法到达的也就意味着无法访问,自然就是垃圾了。

谁可以作为根对象呢?
  • 栈中引用的对象(栈)
  • 类静态属性引用的对象(方法区)
  • 常量引用的对象(方法区)
  • native方法引用的对象(本地方法栈)

垃圾回收算法

标记好垃圾之后,就可以回收了,下面介绍3种回收的算法。

标记-清除法
当垃圾回收器将内存扫描之后,会标记出所有垃圾对象,然后将他们回收。

缺点:不断产生大量的内存碎片,使得内存的使用率变得越来越低。

标记-整理法
在清理垃圾的基础上,多了一步碎片整理的工作。

这样的工作不适合高频率执行,一般,当老年代的空间不足时,会触发一次Full GC,这时就会做碎片整理工作。

复制算法
准备两块一模一样的内存,当第一块内存空间不足时,将所有需要保留的对象拷贝至另一块内存。

然后将前一块内存直接清空。

这样,就既做到了垃圾回收,又做到了碎片整理。

缺点:内存空间浪费一倍

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘新鲜事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值