有没有帮别人做图片的网站赚钱,做红酒的网站有哪些,免费的WORDPRESS主题响应式,wordpress 文章图片布局中1.对象已死吗?
在堆里面存放着Java世界中几乎所有的对象实例#xff0c;垃圾收集器在对堆进行回收前#xff0c;第一件事情就是要确定这些对象之中哪些还“存活”着#xff0c;哪些已经“死去”#xff08;即不可能再被任何途径使用的对象).
引计数法
引用计数算法是一…1.对象已死吗?
在堆里面存放着Java世界中几乎所有的对象实例垃圾收集器在对堆进行回收前第一件事情就是要确定这些对象之中哪些还“存活”着哪些已经“死去”即不可能再被任何途径使用的对象).
引计数法
引用计数算法是一种垃圾回收算法它通过记录每个对象被引用的次数来判断对象是否已经成为垃圾并进行回收。当对象被创建时其引用计数器初始化为0当有其他对象引用该对象时其引用计数器就会加1当引用该对象的对象被销毁时其引用计数器就会减1。当一个对象的引用计数器变为0时即表示该对象已经没有被任何其他对象引用可以被认为是垃圾对象并被回收。
可达性分析
这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点从这些节点开始向下搜索搜索所走过的路径称为引用链Reference Chain当一个对象到GC Roots没有任何引用链相连用图论的话来说就是从GC Roots到这个对象不可达时则证明此对象是不可用的。 在Java语言中可作为GC Roots的对象包括下面几种
虚拟机栈栈帧中的本地变量表中引用的对象。方法区中类静态属性引用的对象。方法区中常量引用的对象。本地方法栈中JNI即一般说的Native方法引用的对象。
2.引用的分类
在JDK 1.2之后Java对引用的概念进行了扩充将引用分为强引用Strong Reference、软引用Soft Reference、弱引用Weak Reference、虚引用Phantom Reference4种这4种引用强度依次逐渐减弱。
强引用就是指在程序代码之中普遍存在的类似“Object obj new Object()”这类的引用只要强引用还存在垃圾收集器永远不会回收掉被引用的对象。软引用是用来描述一些还有用但并非必需的对象。对于软引用关联着的对象在系统将要发生内存溢出异常之前将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存才会抛出内存溢出异常。在JDK 1.2之后提供了SoftReference类来实现软引用。弱引用也是用来描述非必需对象的但是它的强度比软引用更弱一些被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时无论当前内存是否足够都会回收掉只被弱引用关联的对象。在JDK 1.2之后提供了WeakReference类来实现弱引用。虚引用也称为幽灵引用或者幻影引用它是最弱的一种引用关系。一个对象是否有虚引用的存在完全不会对其生存时间构成影响也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2之后提供了PhantomReference类来实现虚引用。
3.三色标记算法
3.1三色标记标记流程
我们知道CMS垃圾回收器是通过可达性分析找到存活对象然后给存活对象打个标记最终在清理的时候如果一个对象没有任何标记就表示这个对象不可达需要被清理。而标记算法就是使用三色标记算法。一般使用白色、黑色和灰色来表示。
白色说明这个对象没有被标记过在初始阶段所有对象都是白色整个过程枚举完最后仍是白色的对象会被当做垃圾对象被清理。灰色这个对象正在被标记但是这个对象直接引用的对象中至少还有一个没有被标记过。黑色对象和他直接引用的所有对象都被标记过对直接引用的对象下一级引用不做要求比如A只引用了BB引用了C、D那么只要A和B都被标记过A就是黑色即使B所引用的C或D还没有被访问到此时B就是灰色。
根据定义jvm中三色标记算法大致流程是
首先从GC Roots开始标记他们所有直接引用对象变成灰色自己本身变为黑色GC Roots对象本身不是垃圾这里我们用队列去存储灰色对象把这些灰色对象放到队列中。然后从队列中取出灰色对象继续进行分析将这个对象所有直接引用变成灰色放入队列中然后这个对象变为黑色如果没有直接引用就直接变为黑色。继续从队列中取出一个灰色对象重复第二步一直到灰色队列为空。分析完后仍然是白色的对象就是不可大对象可以作为垃圾被回收。最后重置标记状态。
下面提供一个例子加深下印象
刚开始所有对象都是白色 三色标记初始阶段标记的初始解读不是CMS的初始标记所有GC Roots直接引用A、B变成灰色放入队列中GC Roots变成了黑色 然后从灰色队列中取出一个灰色对象进行标记比如A、将他直接引用C、D变成灰色放入队列A因为已扫描完它的直接引用对象所以变成黑色 继续从队列中取出灰色对象B但是E没有直接引用其他对象将B标记为黑色 根据上述步骤取出C 、D 对象进行分析他们都没有直接引用其他对象那么就变为黑色 最终分析标记结束后还有一个E对象是白色说明此E 对象是一个垃圾对象不可访问可以被清理掉。
3.2三色标记的缺陷
多标-浮动垃圾标记为不是垃圾对象变成了垃圾
如果整个标记过程是STW的那么没有任何问题但是并发标记过程中用户线程也在运行那么对象引用关系很可能发生变化进而导致前面提到过的两个问题的出现。
比如垃圾回收线程标记回到上面的这个状态 此时E对象已经被标记为黑色表示不是垃圾不会被清除因为处在并发标记阶段同一时刻某个用户线将GC Roots和B对象之间的关系断开了objRoots.b null;)如图 很显然B对象变为了垃圾对象但是由于之前被标记为黑色就不会被当作垃圾回收这种问题称之为浮动垃圾。
浮动垃圾的问题影响不大即使本次不清理下次GC也会被清理而且在并发清理阶段也会产生所谓的浮动垃圾因为用户线程也在不断地断开引用影响不大。
漏标-错杀问题标记为垃圾对象变成了非垃圾
如果一个非垃圾对象变成了垃圾后果就比较严重再回到上面的状态 这里标记线程执行到分析B对象但是刚好发生线程切换操作系统调度用户线程来运行而用户线程先执行A.f E那么引用关系变成了 用户线程做完上述动作GC线程重新开始运行按照之前的流程继续走从对类中取出B对象发现对象没有直接引用那么B对象变成了黑色 接着继续取出 C、D 三个灰色对象他们没有直接引用那么变为黑色对象