Moosphan/Android-Daily-Interview

2019-05-07:谈一谈JAVA垃圾回收机制?

MoJieBlog opened this issue · 5 comments

2019-05-07:谈一谈JAVA垃圾回收机制?

垃圾回收即garbage collection,简称GC,作用是在某块内存不再使用时及时对其进行释放的管理机制。
GC的几个重点就是怎么找到无用对象,怎么对其进行释放,何时进行GC等等
另外说一句,Hotspot VM里堆是分代回收的(分出新生代和老年代,分别进行回收),不知道ART里有没有类似的机制

怎么找到无用对象?

目前来说有两种主流机制,

  • 引用计数:最简单的寻找无用对象的机制,当一个对象被引用一次,引用计数+1,当失去引用时引用计数-1,当此对象引用计数为0时可以直接回收。这种方法有一个显而易见的问题:无法回收被循环引用的对象。
  • 可达性分析:从一个根对象(GC Root)开始向下搜寻,可以认为搜寻到的所有有强引用的对象都是活跃对象,所有找不到的对象都是无用对象,无用对象可能会被即刻回收,也可能进行其他操作(比如执行对象的finalize()方法)
    这里还会引出一点问题:关于强引用,软引用,弱引用和虚引用的分别处理,具体可以看#27

如何释放无用对象?

这个具体是看回收器的实现

何时开始GC?

任何时候都可能,当系统觉得你内存不足了就会开始回收
常见的比如分配对象内存不足时(这里的内存不足有可能不是占用真的很高,可能是内存足够,但是没有连续内存空间去放这个对象),当前堆内存占用超过阈值时,手动调用 System.gc() 建议开始GC时,系统整体内存不足时等

这里举个例子:
你要分配一个大对象(比如一张图片),如果内存不足,可能会发生下面这个情况:

  1. 首先开始一次GC,这次GC不会回收被软引用引用的对象
  2. 如果内存仍然不足,做点其他事情尝试让内存足够,常见的比如:
  • 堆整理:前面说过,内存不足有可能不是占用真的很高,可能是内存足够,但是没有连续内存空间去放这个对象,那就试试整理一下堆看看出来的空间够不够
  • 增大堆内存:尝试申请更大的堆来放对象
  1. 如果内存依然不足,再发起一次GC,这次GC会回收仅被软引用或更弱引用引用的对象(这句话好像有点乱),然后再次尝试分配对象
  2. 如果内存还是不够,那没办法了,抛出OutOfMemoryError

相关文章:
Google官方文档:调试 ART 垃圾回收
ART运行时垃圾收集(GC)过程分析

PS:还有一种方案叫重启试试(逃

简单说一下

回收的垃圾指的是什么?
即虚拟机已经用不到的内存,但曾经被用到

以对象为例
垃圾的判断
1.引用计数算法
2.可达性算法

回收的算法
1.标识、清楚算法
2.复制算法
3.标识、整理算法
4.分代收集算法

对象的分代:年轻代、年老代、终生代

垃圾收集器、内存泄漏等

不细说,可查看我的博客

垃圾回收机制

韭菜明路过,以前写的文章,看完文章还是不懂或者理解不清楚的可以回来找我。

两篇文章让你彻底理解Java虚拟机(一)

两篇文章让你彻底理解Java虚拟机(二)

垃圾回收机制:
当堆内存中的某块区域没有对象引用时,这个内存区域就会变成垃圾,等待垃圾回收器的回收,

强制垃圾回收:
程序只能控制一个对象不被任何引用变量引用,绝对不能控制它的回收。
System.gc();
Runntime.getTuntime().gc();
上面两个方法会建议系统进行垃圾回收,但是系统也有可能不进行回收。
对象的复活可以通过 finalize()方法来实现,