青岛网站seo,高端公司网站设计,小天才电话手表网站,wordpress 加cdn前言
本文参考《深入理解Java虚拟机》#xff0c;主要介绍GC相关的算法#xff0c;引用计数法、可达性分析算法、垃圾收集算法#xff08;分代收集理论#xff0c;标记-清除/整理/复制#xff09;
本系列其他文章链接#xff1a; JVM#xff08;Java Virtual Machine主要介绍GC相关的算法引用计数法、可达性分析算法、垃圾收集算法分代收集理论标记-清除/整理/复制
本系列其他文章链接 JVMJava Virtual Machine内存模型篇 JVMJava Virtual Machine垃圾收集器篇
垃圾收集
当对象不在被使用的时候就被当做垃圾给GC掉以节省内存空间而大部分GC都发生在堆内存中因为这个区域是所有Java线程共享的最容易OOM的地方
引用计数算法
概念
引用计数算法在对象中添加一个引用计数器每当有一个地方引用它的时候计数器值加一当一个引用失效的时候计数器值就减一任何时刻计数器为0的对象就是不可能再被使用的。
存在问题
在特定情况下这个效率还是比较高的算法但是还是会有限问题存在相互引用导致无法被回收即使他们不在被使用了如下图示 图中对象56当他们互相引用但是却没有人使用他们之中任意一个使用计数器计数他们的值永远不为0就不会被回收导致内存泄漏的问题。所以在单独使用计数器是没有办法解决垃圾回收标记问题的。
可达性分析算法
概念
这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始点集从这些节点开始根据引用关系向下搜索搜索过程所走过的路径称为“引用链”如果某个对象到GC Roots间没有任何引用链相连则说明这个对象不可达证明此对象不可能再被使用的。如下图所示
GC Roots对象包括哪些
在Java技术体系固定可作为GC Roots的对象包括以下几种
虚拟机栈栈帧中的本地变量表中引用的对象在方法区类静态属性、常量引用的对象本地方法栈中JNI引用对象Java虚拟机内部的引用所以被同步锁持有的对象
引用
无论是引用计数器还是可达性分析判断对象的存活都和“引用”离不开关系。
在JDK1.2之前Java里面的引用是很传统的定义如果reference类型的数据中存储的数值代表的是另一块内存的起始地址就称该reference数据是代表某块内存、某个对象的引用。
在JDK1.2之后Java对引用的概念进行了扩充将引用分为“强/软/弱/虚引用”这四种引用强度依次减弱
强引用这是最传统的引用赋值Object o new Object();软引用用来描述一些还有用但非必要对象这类对象将在第二次GC被回收JDK1.2提供了SoftReference实现软引用;弱引用用来描述非必须对象比软引用更弱第一次GC就会被回收WeakReference实现弱引用;虚引用最弱的一种引用关系。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收收到一个系统通知。PhantomReference类来实现虚引用;
垃圾收集算法
分代收集理论
大多数垃圾收集器都基于“分代收集理论”进行设计这套理论实际上是一套符合大多数程序运行实际情况的经验法则它建立在两个假说之上
弱分代假说绝大多数对象都是朝生夕死;新生代区域强分代假说熬过越多次垃圾收集过程的对象就越难以消亡;老年代区域
依据这个理论收集器将Java堆划分不同的区域。一个区域放置朝生夕死的对象一个区域放置熬过多次垃圾收集还“活着”的对象。
对于不同的区域新生代、老年代则根据不同的区域使用不同的垃圾收集算法因此有了“Minor GC”、“Major GC”、“Full GC”
标记-清除算法
标记-清除算法首先标记出所需要回收的对象在标记完成后统一回收掉所有被标记的对象或者反过来。这个算法效率是它的优点因为标记完回收掉就可以了不需要其他操作所有这也成了最大的缺点容易出现内存碎片如下图 产生大量不连续的内存碎片可能会导致分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
标记-复制算法
标记-复制算法的底层思想是“半区复制”它将内存按容量划分大小相等的两块每次只使用其中一块当这一块的内存用完了就将存活的对象复制到另一块上然后把使用过的那一块清空等待下一次交换使用。
这样的垃圾收集过程中就只需移动指针位置即可不会存在内存碎片的问题实现简单运行高效但是这样有一个比较大的问题内存始终都是有一块在某种意义上是浪费的。
但是为我们所知道的对象大部分都是朝生夕死的98%的对象都熬不过第一次垃圾回收所以并不需要1:1比例来划分新生代的内存空间。在HotSpot虚拟机中默认分配比例大小是Eden:Survivor(from:to) 8:1:1也就是说每次内存分配只使用Eden和Survivor的另一块。
情况如下图所示
标记-整理算法
标记-复制算法在对象存活率较高时就要进行较多的复制操作效率将会降低。更关键的是如果不想浪费50%的空间就需要有额外的空间进行分配担保以应对被使用的内存中所有对象都100%存活的极端情况所以在老年代一般不能直接选用这种算法。
标记-整理算法就是让所有存活的对象向一端移动然后清理掉边界以外的内存。
标记-清除算法与标记-整理算法的本质差异在于前者是一种非移动式的回收算法后者是移动式的。
END 希望以上内容能给你提供帮助