宁河网站建设,建站案例,寻找做网站的,微信公众号推广软文案例文章目录1.垃圾回收算法**1.1. 标记阶段****1.2. 清除阶段**1.2.1.标记清除算法1.2.2.标记复制算法1.2.3.标记整理算法1.3.引用2.常见的垃圾回收器2.1.Serial回收器2.2.ParNew回收器2.3.Parallel回收器2.4.CMS回收器font color red2.5.G1垃圾回收器ZGC回收器#xff…
文章目录1.垃圾回收算法**1.1. 标记阶段****1.2. 清除阶段**1.2.1.标记清除算法1.2.2.标记复制算法1.2.3.标记整理算法1.3.引用2.常见的垃圾回收器2.1.Serial回收器2.2.ParNew回收器2.3.Parallel回收器2.4.CMS回收器font color red2.5.G1垃圾回收器ZGC回收器实验1.垃圾回收算法 首先我们需要明确的是垃圾回收主要包括以下几个阶段
1.1. 标记阶段
在标记阶段我们举例两个算法 1.引用计数算法 这个算法是python使用的标记算法。 什么是引用计数算法给对象中添加一个引用计数器每当有一个地方引用它时计数器值加当引用失效时计数器值减,引用数量为0的时候,则说明对象没有被任何引用指向,可以认定是”垃圾”对象 这种方法实现比较简单,且效率很高,但是无法解决循环引用的问题,因此在java中没有采用此算法但是在Python中采用的是此算法 2.可达性分析算法 这个算法是java使用的标记算法。 可达性分析算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点从这些节点开始向下搜索搜索所走过的路径称为引用链(Reference Chain)当一个对象到GC Roots没有任何引用链相连时则证明此对象是不可用的。 这个算法的基本思想是通过一系列称为“GC Roots”的对象作为起始点从这些节点向下搜索搜索所走过的路径称为引用链当一个对象到GC Roots没有任何引用链即GC Roots到对象不可达时则证明此对象是不可用的。 2.1.对象的finalization机制
这个机制我称之为救赎机制当对象不可达的时候是且仅有一次救赎的机会的如果这个方法重写过且没执行过就会执行该方法。 如果这个对象被判定为有必要执行finalize()方法那么这个对象将会放置在一个叫做F-Queuc的队列之中并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它。
1.2. 清除阶段
1.2.1.标记清除算法
当堆中的有效内存空间(available memory被耗尽的时候就会停止整个程序也被称为stop the world)然后进行两项工作第一项则是标记第二项则是清除。
标记:collector从引用根节点开始遍历标记所有被引用的对象。一般是在对象的Header中记录为可达对象。清除:collector对堆内存从头到尾进行线性的遍历如果发现某个对象在其Header中没有标记为可达对象则将其回收。
1.2.2.标记复制算法
将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后就将还存活的对象复制另一块去然后再把使用的空间一次清理掉。 优点: 1.不会出现内存碎片问题 2.对于存活对象少的区域新生代)简单高效 缺点: 1.浪费空间并且移动对象开销大
1.2.3.标记整理算法
根据老年代的特点特出的一种标记算法标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动然后直接清理掉端边界以外的内存。 优点: 1.消除了标记-清除算法中内存区域分散不连续的缺点 2.消除了复制算法中内存减半的高额代价 缺点: 1.移动对象开销较大
1.3.引用
内存溢出的原因存在大量无用的但又有强引用的对象无法回收
下面介绍java存在的4种引用
1.强引用 我们经常使用的引用都是强引用强引用触及的对象即便程序报错也不可能回收 。
2.软引用 在程序要内存溢出之前会把软引用对象列入二次回收范围如果本次回收内存仍然不足以运行程序则会把软引用对象回收一般用于高速缓存。
3.弱引用 发现即回收生存到下次内存回收之前一般用于可有可无的缓存。
4.虚引用 对程序完全无影响但是在回收之后可以收到通知
2.常见的垃圾回收器
垃圾回收器的性能指标
1吞吐量即程序运行时间占总时间的百分比。 2低延时单次暂停的时间。 二者属于互斥状态二者不可得兼 低延迟会缩短回收时间因而会进行更多回收准备的无用功因此吞吐量会对吞吐量产生负面影响。 注意CMS在JDK9已经废弃画虚线的表示在后来发行版本组个方式已经废弃
2.1.Serial回收器 这个收集器是一个单线程的收集器但它的“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作更重要的是在它进行垃圾收集时必须暂停其他所有的工作线程直到它收集结束(stop The world)。
serial收集器是最基本、历史最悠久的垃圾收集器了。JDK1.3之前回收新生代唯一的选择。serial收集器作为HotSpot中client模式下的默认新生代垃圾收集器。serial收集器采用复制算法、事行回收和stop-the-world”机制的方式执行内存回收。除了年轻代之外serial收集器还提供用于执行老年代垃圾收集的serial old收集器。Serial old收集器同样也采用了串行回收 和stop the World机制只不过内存回收算法使用的是标记-压缩算法。serial old是运行在client模式下默认的老年代的垃圾回收器Serial old在server模式下主要有两个用途 ①与新生代的Parallelscavenge配合使用②作为老年代CMs收集器的后备垃圾收集方案
2.2.ParNew回收器 如果说serial cc是年轻代中的单线程垃圾收集器那么ParNew收集器则是serial收集器的多线程版本。
ParNew是Parallel的缩写New:只能处理的是新生代ParNew收集器除了采用并行回收的方式执行内存回收外两款垃圾收集器之间几乎没有任何区别。ParNew收集器在年轻代中同样也是采用复制算法、stop-the-world机制。ParNew是很多JVM运行在server模式下新生代的默认垃圾收集器。
2.3.Parallel回收器
Hotspot的年轻代中除了拥有ParNew收集器是基于并行回收的以外Parallel Scavenge收集器同样也采用了复制算法、并行回收和stopthe world”机制。 和ParNew收集器不同Parallel scavenge收集器的目标则是达 一个可控制的吞吐量(Throughput)它也被称为吞吐量优先的垃圾收集器。 自适应调节策略也是Parallel scavenge与ParNew一个重要区别。
2.4.CMS回收器 垃圾收集共分为五个阶段:上图所示初始标记和重新标记会有STW。重新标记会用到三色标记里的增量更新算法。并发清理:这个阶段如果有新增对象会被标记为黑色不做任何处理主要优点:并发收集、低停顿。一XX:UseConcMarkSweepGC:启用cms
CMS的弊端: 1.会产生内存碎片导致并发清除后用户线程可用的空间不足。在无法分配大对象的情况下不得不提前触发Full GC。 2 .CMS收集器对cPu资源非常敏感。在并发阶段它虽然不会导致用户停顿但是会因为占用了一部分线程而导致应用程序变慢总吞吐量会降低。 3.CMS收集器无法处理浮动垃圾。可能出现“Concurrent Mode railure失败而导致另一次 Full GC 的产生。在并发标记阶段由于程序的工作线程和垃圾收集线程是同时运行或者交叉运行的那么在并发标记阶段如果产生新的垃圾对象CMs将无法对这些垃圾对象进行标记最终会导致这些新产生的垃圾对象没有被及时回收从而只能在下一次执行Gc时释放这些之前未被回收的内存空间。
2.5.G1垃圾回收器
G1垃圾回收器是前沿成果
原因就在于应用程序所应对的业务越来越庞大、复杂用户越来越多没有cc就不能保证应用程序正常进行而经常造成STw的Gc又跟不上实际的需求所以才会不断地尝试对cc进行优化。G1 (Garbage-First垃圾回收器是在Java7 update 4之后引入的一个新的垃圾回收器是当今收集器技术发展的最前沿成果之一。
官方给G1设定的目标是在延迟可控的情况下获得尽可能高的吞吐量所以才担当起“全功能收集器”的重任与期望。 因为G1是一个并行回收器它把堆内存分割为很多不相关的区域(Region)物理上不连续的)。使用不同的Region来表示Eden、幸存者o区幸存者1区老年代等。 G1 Gc有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个 Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值)在后台维护一个优先列表每次根据允许的收集时间优先回收价值最大的Region。由于这种方式的侧重点在于回收垃圾最大量的区间(Region)所以我们给G1一个名字:垃圾优先(Garbage First) 。
ZGC回收器实验 JVM的自动垃圾收集虽然减少了开发人员的工作在一定程度上减少了内存泄漏的风险但是由于GC是自动进行的一些无法预知的事情有时候可能产生对应用有害的影响。 延迟增加导致应用的吞吐量和性能 随着时代发展硬件会逐渐便宜应用使用的内存将会越来越大但是又不能增加延迟降低吞吐量 ZGC保证不管在什么情况下延迟不会超过10毫秒。 ZGC最典型的特性是它是一款并发(concurrent)的GC其它的特性如下
它可以标记内存复制和迁移(relocate)内存所有的操作都是并发的同时它有一个并发的引用处理器 其它的垃圾收集器都是使用store barriersZGC使用load barriers用于跟踪内存
lock-unlock-read-load 读内存 use-assign-store-write 写内存
ZGC可以更加灵活的配置大小和策略相比于G1它可以更好的处理非常大(very large)对象的释放ZGC只有一代没有新生代老年代什么的但是ZGC可以支持局部压缩在内存恢复和迁移(reclaim and relocate)时ZGC仍然有很高的性能ZGC依赖NUMA-aware(非均衡存储器访问)需要我们的内存支持这种特点 大部分图片以及内容总结自尚硅谷杜红康老师的尚硅谷宋红康JVM全套教程详解java虚拟机