如何判断是否为垃圾
引用计数法
给对象加一个引用计数器,每当该对象被引用就+1,结束引用就-1。所以就是被引用多少值就是多少,那么当值为0时就没有被引用,被判为垃圾。
该方法原理简单效率高,但存在循环引用的情况。使用时考虑的方面也多。
可达性分析
通过GCRoot这种节点为根节点,根据引用关系向下搜索,搜索过程产生的路径称为“引用链”,如果没有被任何一个引用链标记则说明该对象无法再被引用。
什么节点能作为根节点?
- 虚拟机栈中的引用对象
- 本地方法栈的引用对象
- 方法区的常量的引用对象
- 方法区的静态变量的引用对象
- 被同步锁持有的对象
引用分类
引用的定义
- 如果reference类型的数据中,存储的数值代表的是另一块内存的起始地址,就成这块内存代表着一个引用.
强引用
最传统的引用定义,也是最常用的引用。只要强引用还在就不会被回收。
软引用
可有可无的引用,回收操作后空间仍不足,即要抛出空间异常前,会对软引用做第二次回收,如果还不够则要报出异常。
弱引用
和软引用一样可有可无,但存活时间更短,只要发生回收就会被回收。
虚引用
最弱的引用,无法影响一个对象的存活时间也无法通过虚引用获取一个对象实例。设置虚引用是为了在该对象被回收时收到一个系统通知。
finalize
对象被标记为回收以后不会被立刻回收,还有一次重试的机会。也就是对象被回收要做两步:第一步:没有在引用链上。第二步:是否能用finalize方法,如果已经执行过了或者无法执行则会被回收,调用finalize方法,与引用链搭上关系则不会被回收,否则仍然要被回收。
垃圾回收算法
分代收集理论
该理论依据于两个假说:
- 大部分对象朝生夕死。
- 经过多次垃圾回收都存活下来的对象难以消亡。
这两个假说奠定了常用垃圾回收器的一致设计原则:将java堆划分成不同的区域,将对象按年龄分配到不同的区域当中。
标记-清除
将内存区域中可以到达的对象做标记,清除掉没有被标记的。存在执行效率不稳定,空间碎片化的问题。
标记-复制
将内存空间分为两份,一份用来存储对象,当该空间满了以后就会做标记,将标记的对象移动到另一空间中,再清理该空间。实现简单,运行高效但要牺牲一半的空间。
标记-整理
标记方法和标记-清除一样,在标记好了以后将标记的对象移动到一端,将该端以外的空间清除。
三色标记
白色:还没被回收器访问。
灰色:已被回收器访问,但该对象还有引用未被访问。
黑色:已被访问,该对象的所有引用也被访问。
其他内容摸了。