引用计数器法 可达性分析算法_看完这篇,不要再问我“GC算法与垃圾回收”了...

27de10c40a77af24c69f2b94748503e6.gif更多精彩内容请关注我们 对一名合格的Java程序员而言,GC算法与垃圾回收的实现是一门必修课。 所以,如何把各个零散知识点串起来形成体系就显得非常重要。 本篇主要从以下四个角度出发对该内容进行了探索与总结:
  • 为什么会OOM?

  • 哪些内存需要被回收?

  • 什么时候回收?

  • 垃圾如何回收?

如有兴趣,请往下看

1.为什么会OOM?

以下列代码为例:

import java.util.ArrayList;import java.util.List;public class LimitService {  private List List;  public static void main(String[] args) {    Listlist = new ArrayList<>();    int i = 0;    try {      while (true) {        list.add(new Byte [1024 * 1024] );        i++;      }    } catch (Throwable throwable ) {      throwable.printStackTrace ();      System.out.printIn("次数:" + i);    }  }}

运行该代码会得到如下结果:

java.lang.OutOfMemoryError:Java heap space

Java heap space即Java堆空间不足。

造成这个问题的原因有两个:内存泄漏和内存溢出

对于这两个概念,一个借钱的例子做了很好的解释:

假设你有900w,你的三个亲戚各向你借了250w,不还,这时你借出去的750w便是「内存泄漏」。

而这时又来了个亲戚向你借250w,全部家当150w满足不了这个需求,便导致「内存溢出」,即OutOfMemoryError

2.哪些内存需要被回收?

需要回收的内存即要回收的垃圾,就是那些不可能再被任何途径使用的对象

如何确定一个对象是需要回收的垃圾,有以下两种方法:

2.1引用计数法

给对象添加一个引用计数器,当有其他对象引用该对象时,计数器+1;当引用失效时,计数器-1。

该算法原理简单,容易实现。但是,无法解决对象间循环引用的问题,所以主流的JVM中均没有采用这种算法。

2.2可达性分析

为了解决循环引用问题,出现了可达性分析算法(根搜索算法)来确定垃圾。

基本思路是找一些对象作为遍历的起始点(成为GC Roots),从这些起始点开始搜索,当某个对象并没有和任何GC Root产生关联,则认为这个对象已经不被使用了,可以清除。

3.什么时候回收?

  • 非堆不够用的Metaspace GC

  • old区不够用的Major GC

  • Eden区、survivor区不够用的Minor GC

  • system.gc()

4.垃圾如何回收?

找到不需要的对象,再进行回收。垃圾回收用一句话概括起来容易,但实现高效回收却不简单。

这需要程序员建立一个垃圾回收的思想

为了让程序在运行期间能够进行垃圾回收,需要GC线程与业务线程相互配合。

而为了达到这个目的,标记/清除算法应运而生。

标记阶段从root开始递归地给堆里所有对象打上标记,在清除阶段collector会遍历整个堆,回收没有被标记的对象,将要回收的block插入free_list 链表,还在使用的对象则取消标志位。

但是,标记/清除算法存在效率低、内存不连续(内存碎片)的问题。

于是诞生了以该算法为基础,不断优化而产生的复制算法和标记/整理算法。

掌握算法后,根据对象的生命周期长短采用分代收集便能提高效率。

如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。

Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、版本的虚拟机所提供的垃圾收集器都可能会有很大差别。

c714baf55169f9e5b2651b758608d17d.png

上图展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。

虚拟机所处的区域,则表示它是属于新生代收集器还是老年代收集器。

因为目前并无完美的收集器出现,所以在回收垃圾时只是选择对具体应用最适合的收集器。

下表列出各个收集器的适用场景:

47f200a580c3d28065b987579d946b85.png

更多JVM内容将在后续持续更新,关注我们,做一次知识框架的系统学习吧。

e6059e9b099be8d39970386862c1549a.gif这是一个为 程序员量身定做的求职公众号。 我们有互联网企业创始人,技术类畅销书作者等行业大牛进行 职业生涯经验的分 及专注互联网行业、指导过上万份简历的 资深HR面试tips 分享;累积四年以上的10余项 主流技术的面试题库 ,涵盖各大厂、互联网名企面试题;针对不同岗位的 精选面试简历 。懂你所想,知你所需! 关注我们,有机会获得1V1专属职业规划! c656b9a563e0130db4e3fbbde4ac8ad7.gif转了吗 5ccf4ebcd1548b3eb90b9887b409dc44.gif赞了吗 64e5d31e3cc8aac15818778abe8b4edd.gif在看
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值