JVM垃圾回收

63 阅读3分钟

如何判断是否为垃圾

引用计数法

给对象加一个引用计数器,每当该对象被引用就+1,结束引用就-1。所以就是被引用多少值就是多少,那么当值为0时就没有被引用,被判为垃圾。
该方法原理简单效率高,但存在循环引用的情况。使用时考虑的方面也多。

可达性分析

通过GCRoot这种节点为根节点,根据引用关系向下搜索,搜索过程产生的路径称为“引用链”,如果没有被任何一个引用链标记则说明该对象无法再被引用。

什么节点能作为根节点?

  1. 虚拟机栈中的引用对象
  2. 本地方法栈的引用对象
  3. 方法区的常量的引用对象
  4. 方法区的静态变量的引用对象
  5. 被同步锁持有的对象

引用分类

引用的定义

  • 如果reference类型的数据中,存储的数值代表的是另一块内存的起始地址,就成这块内存代表着一个引用.

强引用

最传统的引用定义,也是最常用的引用。只要强引用还在就不会被回收。

软引用

可有可无的引用,回收操作后空间仍不足,即要抛出空间异常前,会对软引用做第二次回收,如果还不够则要报出异常。

弱引用

和软引用一样可有可无,但存活时间更短,只要发生回收就会被回收。

虚引用

最弱的引用,无法影响一个对象的存活时间也无法通过虚引用获取一个对象实例。设置虚引用是为了在该对象被回收时收到一个系统通知。

finalize

对象被标记为回收以后不会被立刻回收,还有一次重试的机会。也就是对象被回收要做两步:第一步:没有在引用链上。第二步:是否能用finalize方法,如果已经执行过了或者无法执行则会被回收,调用finalize方法,与引用链搭上关系则不会被回收,否则仍然要被回收。

垃圾回收算法

分代收集理论

该理论依据于两个假说:

  1. 大部分对象朝生夕死。
  2. 经过多次垃圾回收都存活下来的对象难以消亡。

这两个假说奠定了常用垃圾回收器的一致设计原则:将java堆划分成不同的区域,将对象按年龄分配到不同的区域当中。

标记-清除

将内存区域中可以到达的对象做标记,清除掉没有被标记的。存在执行效率不稳定,空间碎片化的问题。

标记-复制

将内存空间分为两份,一份用来存储对象,当该空间满了以后就会做标记,将标记的对象移动到另一空间中,再清理该空间。实现简单,运行高效但要牺牲一半的空间。

标记-整理

标记方法和标记-清除一样,在标记好了以后将标记的对象移动到一端,将该端以外的空间清除。

三色标记

白色:还没被回收器访问。
灰色:已被回收器访问,但该对象还有引用未被访问。
黑色:已被访问,该对象的所有引用也被访问。

其他内容摸了。