当前位置: 首页 > news >正文

网站不兼容怎么办啊重庆蒲公英网站建设公司怎么样

网站不兼容怎么办啊,重庆蒲公英网站建设公司怎么样,wordpress图片属性添加图片,营销策划的内容包括哪些简单聊聊G1垃圾回收算法整个流程 --- 理论篇 -- 下 软实时性预测转移时间预测可信度GC 暂停处理的调度并发标记中的暂停处理 分代 G1 GC 模式不同点新生代区域分代对象转移具体转移流程分代选择回收集合设置最大新生代区域数 GC的切换GC执行的时机 总结 上一篇 文章我们简单看了… 简单聊聊G1垃圾回收算法整个流程 --- 理论篇 -- 下 软实时性预测转移时间预测可信度GC 暂停处理的调度并发标记中的暂停处理 分代 G1 GC 模式不同点新生代区域分代对象转移具体转移流程分代选择回收集合设置最大新生代区域数 GC的切换GC执行的时机 总结 上一篇 文章我们简单看了一下G1整个垃圾回收流程但是关于G1如何计算区域回收价值和G1在分代模式下的工作流程这块由于篇幅限制没有进行说明本文主要针对这两块内容进行补齐。 软实时性 在 G1GC 中用户可以设置如下 3 个值 可用内存上限GC 暂停时间上限GC 单位时间 设置可用内存上限是为了避免内存被过度占用。就算是为了实现软实时性也不能让 GC 完全占用内存。 设置GC暂停时间上限 指定的是执行 GC 所导致的用户线程的最大暂停时间。这个最大暂停时间并不包含 G1 GC 的并发处理时间。在多处理器环境下G1 GC 的并发处理时间可以理解成平均分配给用户线程的负载。 CMS垃圾回收算法目标就是缩短用户线程的最大暂停时间所以其适合使用在注重响应时间的Web服务器后端程序中。 有一个权宜之计可以避免 GC 暂停时间超过指定上限那就是频繁地执行暂停时间较短的 GC。虽然这样做确实可以缩短 GC 暂停时间但是 用户线程 的执行也会频繁地被 GC 打断从而导致 用户线程 几乎无法正常执行。 要想避免这个问题需要指定 GC 单位时间。指定该项后G1GC 将在每个单位时间内遵守 GC 的暂停时间上限。如果 GC 暂停时间上限是 1 秒而 GC 单位时间是 3 秒就意味着在任意 3 秒的时间段内GC 的暂停时间不可以超过 1 秒。 a、b、c、d 分别代表一个 GC 单位时间GC 只在 c 中超过了暂停时间上限。 G1 GC 会努力实现软实时性。软实时性的定义是 GC 单位时间内 GC 暂停时间超过上限的次数在用户的容忍范围之内。因此尽管在上图中GC 单位时间 c 内的 GC 暂停时间超过了上限但是只要用户认为可以接受就算是实现了软实时性。 预测转移时间 要想在 GC 暂停时间上限之内完成转移就需要选择可以在这个时间范围内完成转移的回收集合。在往回收集合中添加区域时要先预测一下该区域的转移时间如果超过了 GC 暂停时间上限就不再添加该区域并终止回收集合的选择。 在 G1GC 中由 GC 导致的用户线程的暂停时间称为消耗。转移回收集合的消耗等于扫描转移专用记忆集合中的卡片时的消耗与对象转移时的消耗之和。 具体公式如下所示 公式中各个数值的含义如下: cs : 回收集合V (cs) : 转移回收集合 ( cs ) 的消耗V fixed : 固定消耗U : 扫描脏卡片的平均消耗d : 转移开始时的脏卡数量S : 查找卡片内指向回收集合的引用的消耗r 区域rsSize : 区域的转移专用记忆集合中的卡片总数C : 对象转移时每个字节的消耗liveBytes : 区域内存活对象的总字节数 (大概的值) V ( cs ) 表示某个回收集合 ( cs ) 的转移时间。V fixed 表示转移过程中的固定消耗主要是选择和释放回收集合时的消耗。 V fixed U S C 这几个值的大小受实现方法、运行平台以及应用程序特性等各种环境因素的影响是可变的。因此可以先根据经验设置一些初始值再通过测量各自的实际处理时间来进行修正以提高精度 liveBytes 使用上一篇文章讲到的prev_marked_bytes值对于在并发标记结束后被分配的对象即使是死亡对象也要将其当做存活对象来计数。因此liveBytes并非精确值只是大概的值。 S * rsSize ( r ) C * liveBytes ( r ) 是一个区域的转移消耗。累加求和操作是回收集合内所有区域的转移消耗的总和。U * d 是在转移回收阶段对转移专用记忆集合维护线程未处理完的脏卡片进行扫描的消耗。这些消耗再加上 V fixed 就是总体的消耗了。 在理解了公式中各个参数含义后我们可以把公式翻译成下面的大白话模样: 转移回收集合内所有存活对象的总消耗 固定消耗 扫描剩余脏卡的总消耗 (脏卡数量 * 扫描每个脏卡的平均消耗) 转移回收集合内所有存活对象的消耗 依次扫描回收集合内每个区域,并计算每个区域转移消耗 遍历该区域转移专用记忆集合中每个脏卡,并找出所有指向当前回收区域的引用的总消耗 转移当前区域内所有存活对象的总消耗预测可信度 用户可以通过对消耗的预测值设置预测可信度来调整暂停时间。 预测可信度是一个百分数。如果预测可信度设置为 120%GC 暂停时间会在消耗预测值的基础上上浮 20%。相反如果设置为 80%会在预测值的基础上下浮 20%。预测可信度越高用户的暂停时间就越短相反预测可信度越低用户的暂停时间就越长。 GC 暂停处理的调度 GC 暂停处理必须在合适的时机进行。这是为了遵守本文一开始提到的规则 在 GC 单位时间内不得超过 GC 暂停时间的上限 当堆内空间充足时可以根据需要扩展堆从而延迟转移处理。而且转移处理并不一定发生在并发标记完全结束之后。因此即使并发标记过程中的暂停处理根扫描等延迟开始也不会产生致命的问题。通过这些可知在一般情况下除了堆内空间紧缺时GC 暂停处理发生的时机是可以调度的。 G1GC 中有一个队列名为调度队列其中的元素是暂停处理的开始时间和结束时间的组合。G1GC 使用这个队列来高效地调度 GC 的暂停处理任务。调度队列中保存了最近一次暂停处理的开始时间和结束时间队列的元素。调度队列中元素个数是有上限的如果添加元素时超过上限队列头部中最早添加的元素就会被删除。 调度程序会基于调度队列中的信息来决定下次 GC 暂停的适当时机。如下图所示: 如果像图中②这样执行GC 单位时间内总的 GC 暂停时间会超过上限。但是如果像③这样指定了合适的 GC 暂停时机 ZGC 单位时间内总的 GC 暂停时间就不会超过上限了。 上图中①的 X 表示下次 GC 暂停处理的预测暂停时间。调度程序会计算 X 的开始时刻。 首先假定 X 会像图中②一样立即开始执行由此计算出 GC 单位时间内总的 GC 暂停时间包含 X并检查它是否超过用户指定的 GC 暂停时间上限。如果没有超过上限则认为 X 可以立即开始执行相反如果超过了上限则需要延迟执行 X。GC 暂停时间上限和总的GC 暂停时间的差用 Y 来表示。 图中③将 X 的开始时刻向后延迟了 Y延迟后的开始时刻用 Z 表示。这样GC 单位时间内总的 GC 暂停时间就刚好等于 GC 暂停时间上限。换句话说Z 就是执行 X 的合适时机。 需要注意的是调度程序会保证在任意选取的 GC 单位时间内总的GC 暂停时间不会超过用户指定的 GC 暂停时间上限。假设 GC 单位时间是 3 秒GC 暂停时间上限是 1 秒那么就要像 “第 0 秒到第 3 秒内的GC 暂停时间不超过 1 秒”“第 0.0001 秒到第 3.0001 秒内的 GC 暂停时间不超过 1 秒”“第 0.0003 秒到第 3.0002 秒内的 GC 暂停时间不超过 1秒” 这些情况一样在无论从哪个时刻开始的 3 秒内GC 暂停时间都不会超过上限哪怕 1 秒。下图展示了实际发生过的 GC 暂停的时间片段。 GC 单位时间 a、b、c 中任何一个的总 GC 暂停时间都不超过暂停时间上限。 观察一下 GC 单位时间 a、b、c 范围内总的 GC 暂停时间可以发现GC 暂停处理的确没有超过 GC 暂停时间上限。 当然在 GC 的预测时间不准确或堆内空间不足等导致 GC 必须提前开始时GC 暂停处理还是会超出暂停时间上限。 并发标记中的暂停处理 并发标记中的暂停处理阶段也会以上文中所讲的方法按照合适的间隔执行。具体来说需要在以下 3 个步骤中执行暂停处理 初始标记阶段最终标记阶段收尾工作 但是这些步骤的暂停时间不像转移中的暂停时间一样可控如果暂停时间本身就超过了 GC 暂停时间上限就不能遵守 GC 暂停时间上限了。 在调度 GC 的暂停时机时需要预测暂停时间。一开始需要根据经验来设置并发标记中暂停处理的预测暂停时间。然后可以根据测算出的实际暂停时间并结合过去的执行结果来提高预测暂停时间的精确度。 分代 G1 GC 模式 G1GC 中存在“纯 G1GC 模式”pure garbage-first mode和“分代 G1GC模式”generational garbage-first mode两种模式。前面介绍的内容都是关于纯 G1GC 模式的。本节开始我们将介绍分代 G1GC 模式。 实际上OpenJDK 虽然实现了纯 G1GC 模式但是并没有将这种模式开放给用户。用户们使用的都是分代 G1GC 模式。 不同点 和纯 G1GC 模式相比分代 G1GC 模式主要有以下两个不同点。 区域是分代的回收集合的选择是分代的 在分代 G1 GC 模式中区域被分为新生代区域和老年代区域两类。和其他分代 GC 算法一样分代 G1 GC 的对象也保存了自身在各次转移中存活下来的次数。新生代区域用来存放新生代对象老年代区域用来存放老年代对象。 另外分代 G1 GC 模式也分为新生代 GC 和老年代 GC 。G1 GC 中的新生代 GC 称为完全新生代 GCfully-young collection老年代 GC称为部分新生代 GCpartially-young collection。 完全新生代 GC 和部分新生代 GC 的主要区别在于回收集合的选择 完全新生代 GC 将所有新生代区域选入回收集合部分新生代 GC 将所有新生代区域以及一部分老年代区域选入回收集合。 这里需要注意的是所有的新生代区域都会被选入回收集合。这一点非常重要请务必牢记。 新生代区域 新生代区域可以进一步分为以下两类: 创建区域存活区域 创建区域用来存放刚刚生成、一次也没有被转移过的对象。存活区域用来存放被转移过至少一次的对象。 另外转移专用写屏障不会应用在新生代区域的对象上。因此即使新生代区域的对象存在对其他区域对象的引用被引用区域的转移专用记忆集合中也不会记录引用方的卡片。 对于新生代区域 A 中对象 a 对老年代区域 B 中对象 b 的引用转移专用写屏障是无效的所以转移专用记忆集合 B 不会记录这次引用左图。而对于来自老年代区域对象的引用转移专用写屏障仍然有效右图。 但是为什么新生代区域间不使用转移专用写屏障也可以呢 我们先回顾一下转移专用记忆集合的作用。转移专用记忆集合维护的是区域之间的引用关系因此在转移时无须扫描整个区域就能找到待转移对象所在区域的存活对象。而在分代 G1GC 模式中所有的新生代区域都会被选入回收集合因此在转移新生代区域时所有对象的引用都会被检查。即使被引用区域的转移专用记忆集合中记录了来自新生代区域的引用这些记录也都是重复的信息。因此转移专用记忆集合中不会记录来自新生代区域的引用。 这里可以再次回顾上一篇文章中贴出的对象转移过程伪代码: 1: def evacuate_obj(ref): # 拿到被引用对象的地址 2: from *ref # 如果被引用对象没有被标记,说明是死亡对象,则无需转移 3: if not is_marked(from): 4: return from # 如果被引用对象设置了转发标记说明此时对象已经完成了转移 5: if from.forwarded: # 在被引用对象的转移记忆集合中,重新添加引用方所在区域对自己的引用关系如果有需要的话 6: add_reference(ref, from.forwarded) # 返回被引用对象转移后的新地址 7: return from.forwarding 8: # 为被引用对象分配新的内存空间然后copy过去 9: to allocate($free_region, from.size) 10: copy_data(new, from, from.size) 11: # 设置被引用对象所处旧位置的对象头的转发标记和转发指针 12: from.forwarding to 13: from.forwarded True 14: # 遍历被引用对象引用的子对象列表 15: for child in children(to): # 如果子对象所处区域属于回收集合,则将子对象添加到转移队列中 16: if is_into_collection_set(*child): 17: enqueue($evacuate_queue, child) 18: else: # 在子对象所在区域的转移记忆集合中重新添加引用方所在区域对自己的引用关系 19: add_reference(child, *child) 20: # 这里相当于在新的区域重新创建了对象所以在被引用对象的转移记忆集合中,重新添加引用方所在区域对自己的引用关系 21: add_reference(ref, to) 22: # 返回对象转移后新的地址 23: return to被加入引用队列后后续被处理的流程: 1: def evacuate(): 2: while $evacuate_queue ! Null: 3: ref dequeue($evacuate_queue) 4: *ref evacuate_obj(ref)如果新生代区域C中的对象c1被新生代区域A中的对象a1所引用此时对象转移存在两种情况: 如果先转移c1然后c1旧地址会设置转发标记和转发地址在转移对象a1的时候遍历到子对象c1时发现子对象也位于回收区域内则加入引用队列等待稍后处理同时将对象a1新的引用赋值给引用方然后返回对象a1新的地址。 等到后面子对象c1从引用队列取出处理时发现其已经被转移过了此时会更新a1指向c1的引用关系然后返回c1对象新的地址。 如果先转移a1 遍历到子对象c1时发现子对象也位于回收区域内则加入引用队列等待稍后处理同时将对象a1新的引用赋值给引用方然后返回对象a1新的地址。 等到后面子对象c1从引用队列取出处理时将c1转移到新区域后此时会更新a1指向c1的引用关系然后返回c1对象新的地址。 所以当跨区域引用对应的引用方区域和被引用方区域都位于回收集合中时此时就无需在被引用方的转移专用记忆集合中添加引用方所在卡片了这也是为什么这里新生代区域无需使用写屏障的原因了。 分代对象转移 存活对象保存了自己被转移的次数这个次数称为对象的年龄。转移时对象的年龄如果低于阈值对象就会被转移到存活区域否则就会被转移到老年代区域。将对象转移到老年代区域的行为称为晋升。 如果转移的目标区域满了垃圾回收器就会选择一个空闲的区域把它修改成存活区域或者老年代区域之后作为转移的目标区域使用。 对象被转移到存活区域之后即使该对象引用了回收集合以外的区域也不需要记录在转移专用记忆集合中。关于这一点的原因上一节末尾已经说明了原因。相反往老年代区域转移对象时就必须要记录。因为老年代区域并非每次都会被选入回收集合。 具体转移流程 我们来看一下完全新生代 GC 的执行过程。 完全新生代 GC 不会选择老年代区域而是将所有新生代区域都选入回收集合然后转移回收集合内的存活对象。晋升的对象会被转移到老年代区域其余对象则被转移到存活区域。 部分新生代 GC 则是除了所有新生代区域外还会选择一部分老年代区域进入回收集合。除了回收集合的选择方式部分新生代 GC 和完全新生代 GC 的执行过程是一样的。 分代选择回收集合 刚才介绍过在回收集合的选择方式上完全新生代 GC 和部分新生代GC 有所不同。完全新生代 GC 会选择所有新生代区域而部分新生代GC 会选择所有新生代区域和一部分老年代区域。 分代 GC 的理论基础是大多数对象是“朝生夕死”的。因此分代 G1GC模式也是通过选择回收集合的方式来确保总是优先转移新生代区域从而积极地释放年轻对象的内存空间。 不过选择全部新生代区域的做法可能会打破软实时性。如果新生代区域数太多就有可能无法遵守用户设置的 GC 暂停时间上限。要想避免这个问题分代 G1GC 模式就需要计算出合理的最大新生代区域数。 设置最大新生代区域数 完全新生代 GC 和部分新生代 GC 关于最大新生代区域数的计算方法是不一样的。 完全新生代 GC 的最大新生代区域数是在遵守 GC 暂停时间上限的前提下尽量设置较大的值。即根据过去的转移时间记录预测出单个新生代区域转移所需的大概时间然后基于这个时间计算出刚好不超过 GC暂停时间上限的最大新生代区域数。完全新生代 GC 的名字由来就是“尽可能完全地转移新生代区域”。 而部分新生代 GC 的最大新生代区域数是在遵守 GC 单位时间的前提下尽量设置较小的值: 首先采用软实时性一节中介绍的方法计算出下次能够进行 GC 暂停处理的时机。然后预测出在这个“时机”之前大概能回收多少个区域并以此作为新生代区域的最大数目。当预测值命中时达到最大新生代区域数的时机刚好就是下次能够进行 GC 暂停处理的时机因此能够遵守 GC 单位时间。另外因为最大新生代区域数设置的是最小值所以被选入回收集合的新生代区域数也是最少的。这样一来距离 GC 暂停时间上限很可能还有一段时间就可以往回收集合里添加一些老年代区域。 部分新生代 GC 的名字由来就是“尽可能少地转移新生代区域”。 最大新生代区域数的设置发生在并发标记结束之后。 GC的切换 垃圾回收器在选择 GC 算法时通常会选择部分新生代 GC只有在使用完全新生代 GC 效率更高时才会切换为完全新生代 GC。切换的时间点和设置最大新生代区域数时一样都是在并发标记结束之后。 首先参考并发标记中标记出的死亡对象个数预测出下次部分新生代GC 的转移效率。然后根据过去的完全新生代 GC 的转移效率预测出下次完全新生代 GC 的转移效率。如果预测出完全新生代 GC 的转移效率更高则切换为完全新生代 GC。 GC执行的时机 当新生代区域数达到上限时会触发转移的执行。换句话说通过调节最大新生代区域数可以控制转移执行的时机。 当转移完成并通过以下 4 项检查之后会开始执行并发标记: 不在并发标记执行过程中并发标记的结果已被上次转移使用完已经使用了一定量的堆内存默认是全部堆内存的 45% 以上相比上次转移完成之后堆内存的使用量有所增加 其中第二步是为了避免重复地并发标记。如果有并发标记的结果尚未在转移过程中被使用则不会开始并发标记。 需要注意的是并发标记过程中的所有暂停处理都需要遵守程序对于GC 暂停处理的调度以适当的时间间隔来执行。 总结 GC 的各种处理之间关系非常复杂这里我们用一张图来总结一下。下图展示了 mutator (用户线程) 和 GC 的执行关系示例: 图中并列的箭头表示可能会并行执行的处理 从上图中可以看出转移专用记忆集合维护线程和 mutator(用户线程) 在大多数时间中是并发执行的但是在存活对象计数时转移专用记忆集合维护线程也是暂停的。 并发计数阶段是和用户线程并行执行的到此时为止所有存活对象都已经被标记出来了G1后续会按照当前时刻快照进行筛选回收所以即使此刻用户线程又更改了引用关系也不会有什么影响所以可以停止掉记忆集合线程。当进入后续筛选回收阶段时还是处于STW状态相当于是以最终标记这一刻的快照为准进行筛选加对象转移所以以上论述都是为了证明此刻停掉记忆集合线程没有什么关系用户在计数阶段变更的引用关系会在下一波GC时再被处理。 还有一点需要注意那就是转移处理可能发生在并发标记中暂停处理以外的所有时刻。比如在并发标记阶段或者存活对象计数的过程中都可能执行转移。 下面对G1垃圾回收算法的优缺点进行总结 优点: 首先G1GC 具备软实时性这是一个很大的优点。对于要求软实时性的应用程序可以由用户控制 GC 暂停时间。其次它能够充分发挥高配置机器的性能大幅缩减 GC 暂停时间这一点也值得表扬。虽然考虑到算法总有一些必须要暂停的阶段但这些阶段也可以通过尽可能地并行执行来进一步缩短暂停时间。再次它通过将写屏障的处理粒度由对象粒度改为更粗的卡片粒度降低了写屏障发生的频率。这也是缩短暂停时间的一个手段。另外因为有转移所以区域内不会产生内存碎片。由此可以提高引用的局部性和对象存储空间分配的速度。与其他具备软实时性的 GC 相比G1GC 的吞吐量保持在较高水平。近年很多具备软实时性的 GC 会通过频繁地执行“以对象为单位进行复制”这种更细粒度的暂停处理来缩短 GC 暂停时间从而达成软实时性。因此无论如何它们的吞吐量都是下降的。另外这些 GC 中死亡对象的回收处理可能存在延迟因此内存的使用效率也不高。而 G1GC 以区域这种较粗的粒度来频繁地执行用户指定时间内的暂停处理所以暂停时间会稍微长一些它的吞吐量也会高一些。此外通过在转移时选择合适的回收集合还能够更高效地回收死亡对象。 缺点: G1 GC 的适用对象被限定为“搭载多核处理器、拥有大容量内存的机器”。在多数环境下我们并不能发挥出它的性能。适用环境受限可以说是它的一个缺点。另外在转移时尽管区域内不会出现碎片化但是会出现以区域为单位整个堆的碎片化。和普通的 GC 复制算法相比这一点算是缺点。
http://www.sadfv.cn/news/400194/

相关文章:

  • 凡科2网站需要备案吗国贸附近网站建设
  • 盐城网站建设有限公司俄语学习网站
  • 网站优化最为重要的内容是如何帮公司做网站
  • 宣城市住房和城乡建设局网站首页做购物网站需要什么服务器
  • 成都电商网站开发深圳市文化广电旅游体育局
  • 如何与对方网站做相互链接中山市城市建设档案馆网站
  • 网站设计线框图wordpress底部页面在哪里
  • 彩票网站开发技术国家建设部网站2018年
  • 此网站服务器不在国内维护网站开发的销售
  • 手机wap网站免费制作为什么wordpress菜单编辑不
  • 网站备案被拒绝wordpress自定义文章列表
  • 用备忘录制作一个网站的制作淘宝店铺购买价格
  • 朝阳市网站制作网页设计放大镜的实验报告
  • 嘉兴网站建设服务wordpress apache 配置
  • 山东网站方案画册设计欣赏
  • 网站开发语言检测企业网站排版规则
  • 如何创建网站老鱼网win10可以自己做网站
  • 怎么做兼职类网站吗新浪网页版登录
  • 网站优化的内容福州网站建设印秀
  • 简单旅游网站开发网络营销方式和平台推广
  • 台州找人做网站如何建设一个好的网站
  • 购物类网站模板手工艺品出口网站建设策划书
  • 做什么网站能吸引流量网站title怎么修改
  • 免费单页网站上海网站开发设计培训
  • 建筑网站资料白银市城县建设局网站
  • grace+wordpress佛山seo网站排名
  • 网站空间免费嵌入式开发工程师需要学什么
  • 网站服务器放置地网站建设期末作业要求
  • 郑州网站建设公凡客诚品简介
  • 旅游网站开发设计报告书国外域名的网站