一文了解什么JVM垃圾回收

如何判定一个对象是不是垃圾

1, 引用计数算法

  通过对一个对象的引用进行计数(初始为0),如果一个对象被引用那么就给这个对象的引用计数器+1,当放弃一次这个对象引用,那么引用计数器-1。在进行垃圾回收时,如果一个对象的引用计数器的值为0,那么这个对象就可以被判定为垃圾,可以被回收;反之,不会被回收。

  但是这会一个问题出现,如果两个对象循环依赖引用,如A的属性为B,而B的属性为A,那么引用计数器就一直不会为0,对象永远不会被回收,因此在JVM中并没有采用这种算法来判定垃圾,这个算法主要用于如python等语言的内存回收管理,当然使用此算法的语言已经解决了循环依赖的问题

2,GC Roots可达法

  在JVM中采用的是GC Roots可达法来判定一个对象是否是垃圾。如果一个对象的引用链可以到达一个GC Roots那么这个对象不是垃圾;反之,则判定是垃圾。
  GC Roots就是一些特殊的对象,譬如 全局静态变量、全局静态常量、局部变量表中引用的变量、Native方法引用的对象

垃圾回收算法

记录那些是空闲的内存方法
  1,指针碰撞,即维护一个指针,指针的一端是已经使用了的内存,另一端是未使用的内存,适用于复制算法、标志整理法。但不适用于标志清除法,因为他会产生很多的内存碎片。
  2,空闲列表,即维护一个列表,列表中记录了那一段空间是未被分配的、空闲的。标志清除法,一般就采用空闲列表记录空闲内存。

1,复制算法

  将内存分为三块,一块为较大的Eden区(后文用E区表示),两块较小的Survivor(S1+S2)区,在分配内存的时候,只使用一块Eden区+一块Survivor(假设是E+S1,S1和S2是等价的,无区别的),首先使用Eden区,当E区不够用的时候在使用S1区。当进行垃圾回收的时候,将E,S1上存活的对象复制到S2区,然后清理掉E区、S1区,接着使用E+S2来分配内存。
  如果将Eden区设置过大,Survivor区设置过小,很有可能出现S2不足以存放E+S1存活的对象;如果将Survivor区设置过大,那么在使用的过程中总有一块Survivor区未被使用,即内存的浪费。因此复制算法一般用于新生代的垃圾回收,新生代的对象一般朝生夕死,在hotspot虚拟机中,采用Eden:Survivor=8:1,即Eden区占80%的内存,2块Survivor各占10%,只有10%的内存被浪费(可以通过-XX:SurviviorRatio设置占比)。

   如-XX:SurvivorRatio=8 Survivor:Eden = 1:8即Survivor占80%,两块Survivor各占10%

  那么如果Survivor不够用了应该怎么办呢?
  那么会采用分配担保机制去借老年代的内存,由于一共有多少对象活下来,在未完成回收之前是不清楚的,在进行MinorGC(即垃圾回收新生代)之前,jvm会计算老年代剩余的连续空间大小是否大于新生代的对象总大小。
  如果大于那么进行MinorGC肯定是没问题的,因为就算Survivor不够用,老年底的空闲内存也完全足够暂存其他存活的对象。
  如果老年代空间小于存活新生代对象的总大小,但大于历次晋升到老年代(当新生代的对象的分代年龄达到一定值即会晋升到老年代)的平均值,那么有较大的可能,使老年代空间可以担保进行MinorGC,但是也是有一定风险的(即实际老年代也放不下这么多的新生代对象)。那么此时(或者老年代空间也小于历次晋升平均值)会出发一次FullGC(即垃圾回收新生代和老生代)。

2,标志清除法

  首先遍历一遍对象,将判定为垃圾的对象进行清除,不需要将内存分为Eden、Survivor,减少了内存的浪费,但是这样会产生大量的不连续的、散落的内存碎片,为后面内存分配造成困难。一般用于老年代。

在这里插入图片描述
假设红色代表进行垃圾回收判定为非垃圾的对象,黑色代表判定为垃圾的对象,白色为未分配的内存,那么进行一次标志清除算法后,如下图,会产生很多零碎的非分配内存空间。
在这里插入图片描述

3,标志整理法

  标志整理算法,首先标记垃圾对象,再将非垃圾对象向一个方向移动,可以覆盖度垃圾对象,最后清除边界的垃圾对象。这样便很好的解决了内存碎片的问题。一般用于老年代。
经过
经过标志整理法后,所有存活对象(红色)向一个方向移动,并且清除掉了边界的垃圾对象。
在这里插入图片描述

三种算法比较

**
同:
都是基于GCRoots可达法来判定一个对象是否是垃圾。
异:
复制算法常用于新生代,标志清除、标志整理常用于老年代。
内存利用率:标志清除=标志整理>复制算法
内存整齐度:复制算法=标志整理>标志清除
时间效率:复制算法>标志整理=标志清除**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值