Java垃圾回收

在进行垃圾回收之前需要考虑三个问题:

1.哪种内存需要回收。

2.什么时候回收。

3.怎么回收

判断对象是否存活

 1.引用计数法

   给对象增加一个引用计数器,每当一个地方引用它,计数器就加1,当引用失效时,计数器减1.任何时刻计数为0的对象就是不能再被使用,即对象已死。

  引用计数法实现简单,判断效率也比较高,在大部分情况下都是一个不错的算法。但是在主流的JVM中没有选用引用计数法来管理内存,最主要的原因是引用计数器无法解决对象循环引用问题。

 

2.可达性分析算法

主流的语言都采用的是可达性分析算法。

核心思想:通过一系列称为“GC Roots”的对象为起始点,从这些节点开始向下搜索,搜索走过的路径称之为“引用链”,当一个对象到GC Roots没有任何的引用链相连时(从GC Roots到这个对象不可达时),证明此对象是不可用的。

在Java中,可作为GC Roots的对象包含下面几种:

(1)虚拟机栈(栈帧中的本地变量表)中引用的对象

(2)方法区中类静态属性引用的对象

(3)方法区中敞亮引用的对象

(4)本地方法栈中JNI(Native方法)引用的对象

 

垃圾回收算法

标记清除算法:首先标记出需要回收的对象,在标记完成后统一回收所有标记的对象,但是存在两个问题:

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

2.空间问题:标记清除后会产生大量不连续的内存碎片,空间碎片太多会导致以后在程序运行中需要分配叫大对象时,无法找到足够连续内存而不得不提前出发另一次垃圾回收。

复制算法:是将内存划分为两块大小相等的区域,每次使用时都只用其中一块区域,当发生垃圾回收时会将存活的对象全部复制到未使用的区域,然后对之前的区域进行全部回收。

这样简单高效,而且还不存在标记清除算法中的内存碎片问题,但就是有点浪费内存。

标记整理算法

复制算法如果在存活对象较多时效率明显会降低,特别是在老年代中并没有多余的内存区域可以提供内存担保。

所以老年代中使用的时候标记整理算法,它的原理和标记清除算法类似,只是最后一步的清除改为了将存活对象全部移动到一端,然后再将边界之外的内存全部回收。

 

分代回收算法

现代多数的商用 JVM 的垃圾收集器都是采用的分代回收算法,和之前所提到的算法并没有新的内容。

只是将 Java 堆分为了新生代和老年代。由于新生代中存活对象较少,所以采用复制算法,简单高效。

而老年代中对象较多,并且没有可以担保的内存区域,所以一般采用标记清除或者是标记整理算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值