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

文库网站开发教程济南制作网站公司吗

文库网站开发教程,济南制作网站公司吗,WordPress设置页数,wordpress表单支付垃圾回收#xff08;GC#xff09;详解 一. 死亡对象的判断算法1. 引用计数算法2. 可达性分析算法 二. 垃圾回收算法1. 标记-清除算法2. 复制算法3. 标记-整理算法4. 分代算法 三. STW1. 为什么要 STW2. 什么情况下 STW 四. 垃圾收集器1. CMS收集器#xff08;老年代收集器GC详解 一. 死亡对象的判断算法1. 引用计数算法2. 可达性分析算法 二. 垃圾回收算法1. 标记-清除算法2. 复制算法3. 标记-整理算法4. 分代算法 三. STW1. 为什么要 STW2. 什么情况下 STW 四. 垃圾收集器1. CMS收集器老年代收集器并发GC2. G1收集器(唯一一款全区域的垃圾回收器) 总结一个对象的一生 垃圾回收 Garbage Collection的区域 对于程序计数器、虚拟机栈、本地方法栈而言其生命周期与相关线程有关随线程而生随线程而灭。并且这三个区域的内存分配与回收具有确定性当方法结束或者线程结束时内存就自然跟着线程回收了。对于方法区是类加载时使用的类卸载时释放但是类卸载操作是一个非常低频的操作。所以内存分配和回收主要关注的是堆这个区域。 Java 堆中存放着几乎所有的对象实例垃圾回收器在对堆进行垃圾回收前首先要判断这些对象哪些还存活哪些已经死去。 一. 死亡对象的判断算法 1. 引用计数算法 引用计数描述的算法为: 给对象增加一个引用计数器每当有一个地方引用它时计数器就1当引用失效时计数器就-1任何时刻计数器为 0 的对象就是不能再被使用的即对象已死。 引用计数法实现简单判定效率也比较高在大部分情况下都是一个不错的算法。 缺点 空间利用率低 每个对象都得搭配一个计数器如果对象本身比较大多出 4 个字节不算啥但是如果对象本身就很小比如 4 个字节再加上计数器相当于浪费了一半的空间。有循环引用问题。 观察循环引用问题 class Test {public Object instance null;public static void testGC() {Test test1 new Test();Test test2 new Test();test1.instance test2;test2.instance test1;test1 null;test2 null;} }test1、test2 两个对象的引用计数器都不为 0 但是其实 test1 和 test2 都是无法被外界代码访问到的。 2. 可达性分析算法 Java并不采用引用计数法来判断对象是否已死而采用可达性分析来判断对象是否存活。 此算法的核心思想为 : 通过一系列称为GC Roots的对象作为起始点从这些节点开始向下搜索搜索走过的路径称之为引用链当一个对象到 GC Roots 没有任何的引用链相连时(从GC Roots到这个对象不可达)时证明此对象是不可用的。 以下图为例 对象Object5-Object7之间虽然彼此还有关联但是它们到GC Roots是不可达的因此他们会被判定为可回收对象。 在Java语言中可作为GC Roots的对象包含下面几种: 虚拟机栈(栈帧中的本地变量表)中引用的对象方法区中类静态属性引用的对象方法区中常量引用的对象本地方法栈中 JNI(Native方法)引用的对象。 优点 克服了基于引用计数的两个缺点空间利用率低和循环引用问题。 缺点 系统开销大遍历一次可能比较慢。 二. 垃圾回收算法 将死亡对象标记出来之后就可以进行垃圾回收操作了。 1. 标记-清除算法 标记-清除算法是最基础的收集算法。 算法分为标记和清除两个阶段 : 首先标记出所有需要回收的对象在标记完成后统一回收所有被标记的对象。 标记-清除算法的不足主要有两个 : 效率问题 : 标记和清除这两个过程的效率都不高空间问题 : 标记清除后会产生大量不连续的内存碎片空间碎片太多可能会导致以后在程序运行中需要分配较大对象时无法找到足够连续内存而不得不提前触发另一次垃圾收集。 后续的收集算法都是基于这种思路并对其不足加以改进而已。 2. 复制算法 复制算法是为了解决 “标记-清理” 的内存碎片问题。 它将可用内存按容量划分为大小相等的两块每次只使用其中的一块当这块内存需要进行垃圾回收时会将此区域还存活着的对象复制到另一块上面然后再把已经使用过的内存区域一次清理掉。 这样做的好处是每次都是对整个半区进行内存回收内存分配时也就不需要考虑内存碎片等复杂情况只需要移动堆顶指针按顺序分配即可。此算法实现简单运行高效。 复制算法的缺点 空间利用率低。若要保留的对象比较多要释放的对象少此时复制开销就很大。 3. 标记-整理算法 复制收集算法在对象存活率较高时会进行比较多的复制操作效率会变低。因此在老年代一般不能使用复制算法。 针对老年代的特点提出了一种称之为标记-整理算法。标记过程仍与标记-清除过程一致但后续步骤不是直接对可回收对象进行清理而是让所有存活对象都向一端移动然后直接清理掉端边界以外的内存。 注意 标记整理算法也涉及到对象的复制相比于复制算法解决了空间利用率低的问题但是仍然没有解决复制搬运元素开销大的问题。 虽然标记整理算法同样需要复制 但是标记整理算法通常需要复制移动较少的对象因为老年代的对象生命周期较长一些对象在不同的垃圾回收周期中仍然存活不需要频繁地移动。相比之下复制算法在每次垃圾回收时都要复制大部分对象。 4. 分代算法 针对对象进行分类根据年龄划分一个对象熬过一轮 GC 扫描成为涨了一岁针对不同的对象采用不同的方案。 新生代中使用复制算法老年代中使用标记整理算法。 现在的商用虚拟机 (包括 HotSpot 都是采用复制算法来回收新生代) 新生代中98%的对象都是朝生夕死的所以并不需要按照1 : 1的比例来划分内存空间而是将内存(新生代内存)分为一块较大的 Eden (伊甸园)空间和两块较小的 Survivor (幸存者)空间每次使用 Eden 和其中一块Survivor两个Survivor区域一个称为From区另一个称为To区域。当回收时将 Eden 和 Survivor 中还存活的对象一次性复制到另一块 Survivor 空间上最后清理掉 Eden 和刚才用过的 Survivor 空间。 当 Survivor 空间不够用时需要依赖其他内存(老年代)进行分配担保。 HotSpot 默认 Eden 与 Survivor 的大小比例是8 : 1也就是说 Eden:Survivor From : Survivor To 8:1:1。 所以每次新生代可用内存空间为整个新生代容量的90%,而剩下的10%用来存放回收后存活的对象。 HotSpot实现的复制算法流程如下: 当 Eden 区满的时候,会触发第一次 Minor gc,把还活着的对象拷贝到 Survivor From 区 当 Eden 区再次触发 Minor gc 的时候,会扫描 Eden 区和 From 区域,对两个区域进行垃圾回收,经过这次回收后还存活的对象,则直接复制到 To 区域,并将 Eden 和 From 区域清空。当后续 Eden 又发生 Minor gc 的时候,会对 Eden 和 To 区域进行垃圾回收,存活的对象复制到 From 区域,并将 Eden 和 To 区域清空。部分对象会在 From 和 To 区域中复制来复制去,如此交换 15 次(由 JVM 参数 MaxTenuringThreshold 决定,这个参数默认是 15 ),最终如果还是存活,就存入到老年代。 基本经验规律一个对象越老继续存活的可能性越大要死早死了所以老年代的扫描频率远远低于新生代老年代中使用标记整理的方式进行回收。 当前 JVM 垃圾收集都采用的是分代收集(Generational Collection)算法这个算法并没有新思想只是根据对象存活周期的不同将内存划分为几块。一般是把 Java 堆分为新生代和老年代。在新生代中每次垃圾回收都有大批对象死去只有少量存活因此我们采用复制算法而老年代中对象存活率高、没有额外空间对它进行分配担保就必须采用标记-清理或者标记-整理算法。 哪些对象会进入新生代哪些对象会进入老年代 新生代一般创建的对象都会进入新生代老年代大对象和经历了 N 次一般情况默认是 15 次垃圾回收依然存活下来的对象会从新生代移动到老年代。大对象拷贝开销比较大不适合使用复制算法直接进入老年代 面试题 : 请问了解 Minor GC 和 Major GC 么这两种 GC 有什么不一样吗? Minor GC 又称为新生代 GC : 指的是发生在新生代的垃圾收集。因为Java对象大多都具备朝生夕灭的特性因此 Minor GC(采用复制算法)非常频繁一般回收速度也比较快。Major GC 又称为 老年代 GC 或者 Full GC : 指发生在老年代的垃圾收集。出现了Major GC经常会伴随至少一次的 Minor GC(并非绝对在Parallel Scavenge收集器中就有直接进行 Full GC 的策略选择过程), 所以又称为 Full GC。Minor GC通常比Full GC频繁发生因为新生代中的对象生命周期较短。Major GC的速度一般会比 Minor GC 慢10倍以上。 三. STW STWStop-The-World是垃圾回收中的一种现象它表示在某些情况下应用程序的所有线程都会被暂停以便执行垃圾回收操作。STW 是为了确保垃圾回收器可以安全地执行清理和整理内存的工作而不会受到应用程序线程的干扰。 1. 为什么要 STW 为了确保垃圾回收操作的正确性和安全性。尽管 STW 会导致应用程序线程的暂停但它是必要的因为在垃圾回收过程中需要满足以下条件 一致性在执行垃圾回收期间垃圾回收器需要准确地知道哪些对象是活动的哪些是垃圾的。如果在执行垃圾回收时应用程序线程仍然可以创建、修改或引用对象那么垃圾回收器将无法确定对象的状态可能会导致对象被错误地清理或保留。 引用更新在垃圾回收期间垃圾回收器需要更新对象之间的引用关系以确保引用的正确性。如果应用程序线程在垃圾回收期间继续运行可能会导致引用关系混乱垃圾回收器无法正确地更新引用。 内存整理在垃圾回收中可能会发生内存整理操作例如对象的移动以减少内存碎片或提高内存利用率。如果应用程序线程继续操作内存可能会导致内存整理的不一致性从而破坏程序的状态。 垃圾对象清理STW 允许垃圾回收器安全地删除不再被引用的垃圾对象而不会涉及到应用程序线程对这些对象的操作。 2. 什么情况下 STW minor GC 新生代垃圾回收和 major GC 老年代垃圾回收都会触发 STW。 四. 垃圾收集器 垃圾收集器就是内存回收的具体实现。 垃圾收集器的作用垃圾收集器是为了保证程序能够正常、持久运行的一种技术它是将程序中不用的死亡对象也就是垃圾对象进行清除从而保证了新对象能够正常申请到内存空间。 以下这些收集器是 HotSpot 虚拟机随着不同版本推出的重要的垃圾收集器 上图展示了 7 种作用于不同分代的收集器如果两个收集器之间存在连线就说明他们之间可以搭配使用。 所处的区域表示它是属于新生代收集器还是老年代收集器。在讲具体的收集器之前我们先来明确三个概念: 注意这里的并行和并发只是指 GC 时的并行和并发。 并行(Parallel) : 指多条垃圾收集线程并行工作用户线程仍处于等待状态并发(Concurrent) : 指用户线程与垃圾收集线程同时执行(不一定并行可能会交替执行)用户程序继续运行而垃圾收集程序在另外一个CPU上。吞吐量:就是 CPU 用于运行用户代码的时间与 CPU 总消耗时间的比值。可以简单理解为单位时间内回收的垃圾数量 吞 吐 量 运 行 用 户 代 码 时 间 /(运 行 用 户 代 码 时 间 垃 圾 收 集 时 间) 例如虚拟机总共运行了100分钟其中垃圾收集花掉1分钟那吞吐量就是99%。 为什么会有这么多垃圾收集器 自从有了 Java 语言就有了垃圾收集器这么多垃圾收集器其实是历史发展的产物。 最早的垃圾收集器为 Serial也就是串行执行的垃圾收集器Serial Old 为串行的老年代收集器而随着时间的发展为了提升更高的性能于是有了 Serial 多线程版的垃圾收集器 ParNew。后来人们想要更高吞吐量 的垃圾收集器吞吐量是指单位时间内成功回收垃圾的数量于是就有了吞吐量优先的垃圾收集器 Parallel Scavenge吞吐量优先的新生代垃圾收集器和 Parallel Old吞吐量优先的老年代垃圾收集器。随着技术的发展后来又有了 CMSConcurrent Mark Sweep垃圾收集器CMS 可以兼顾吞吐量和以获取最短回收停顿时间为目标的收集器在 JDK 1.8包含之前 BS 系统的主流垃圾收集器而在 JDK1.8 之后出现了第一个既不完全属于新生代也不完全属于老年代的垃圾收集器 G1Garbage FirstG1 提供了基本不需要停止程序就可以收集垃圾的技术。 1. CMS收集器老年代收集器并发GC 特性 CMSConcurrent Mark Sweep收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上这类应用尤其重视服务的响应速度希望系统停顿时间最短以给用户带来较好的体验。CMS收集器就非常符合这类应用的需求。 CMS收集器是基于“标记—清除”算法实现的它的运作过程相对于前面几种收集器来说更复杂一些整个过程分为4个步骤 初始标记CMS initial mark 初始标记仅仅只是标记一下 GC Roots 能直接关联到的对象速度很快需要 STW“Stop The World”。并发标记CMS concurrent mark 并发标记阶段就是进行GC Roots Tracing 的过程。重新标记CMS remark 重新标记阶段是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录这个阶段的停顿时间一般会比初始标记阶段稍长一些但远比并发标记的时间短仍然需要“Stop The World”。并发清除CMS concurrent sweep 并发清除阶段会清除对象。 由于整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作所以从总体上来说CMS收集器的内存回收过程是与用户线程一起并发执行的。 优点 CMS是一款优秀的收集器它的主要优点在名字上已经体现出来了并发收集、低停顿。 缺点 CMS收集器对CPU资源非常敏感 在并发阶段它虽然不会导致用户线程停顿但是会因为占用了一部分线程或者说CPU资源而导致应用程序变慢总吞吐量会降低。 CMS收集器无法处理浮动垃圾 CMS收集器无法处理浮动垃圾可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。 由于CMS并发清理阶段用户线程还在运行着伴随程序运行自然就还会有新的垃圾不断产生这一部分垃圾出现在标记过程之后CMS无法在当次收集中处理掉它们只好留待下一次GC时再清理掉。这一部分垃圾就称为“浮动垃圾”。 也是由于在垃圾收集阶段用户线程还需要运行那也就还需要预留有足够的内存空间给用户线程使用因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集需要预留一部分空间提供并发收集时的程序运作使用。 要是 CMS 运行期间预留的内存无法满足程序需要就会出现一次“Concurrent Mode Failure”失败这时虚拟机将启动后备预案临时启用 Serial Old 收集器来重新进行老年代的垃圾收集这样停顿时间就很长了。 CMS收集器会产生大量空间碎片 CMS 是一款基于“标记—清除”算法实现的收集器这意味着收集结束时会有大量空间碎片产生。空间碎片过多时将会给大对象分配带来很大麻烦往往会出现老年代还有很大空间剩余但是无法找到足够大的连续空间来分配当前对象不得不提前触发一次 Full GC。 2. G1收集器(唯一一款全区域的垃圾回收器) G1Garbage First垃圾回收器是用在 heap memory 很大的情况下把heap划分为很多很多的 region 块然后并行的对其进行垃圾回收。 G1垃圾回收器在清除实例所占用的内存空间后还会做内存压缩。 G1垃圾回收器回收 region 的时候基本不会STW而是基于 most garbage 优先回收(整体来看是基于标记-整理算法局部(两个 region 之间)基于复制算法) 的策略来对 region 进行垃圾回收的。 一个region有可能属于EdenSurvivor 或者 Tenured 内存区域。图中的 E 表示该 region 属于 Eden 内存区域S 表示属于 Survivor 内存区域T 表示属于 Tenured 内存区域。图中空白的表示未使用的内存空间。 G1垃圾收集器还增加了一种新的内存区域叫做 Humongous 内存区域如图中的H块。这种内存区域主要用于存储大对象-即大小超过一个region 大小的50%的对象。 年轻代垃圾收集: 在 G1 垃圾收集器中年轻代的垃圾回收过程使用复制算法。把 Eden 区和 Survivor 区的对象复制到新的 Survivor 区域。 如下图 老年代垃收集 对于老年代上的垃圾收集G1垃圾收集器也分为4个阶段基本跟 CMS 垃圾收集器一样但略有不同 初始标记(Initial Mark)阶段 同CMS垃圾收集器的 Initial Mark 阶段一样G1 也需要暂停应用程序的执行它会标记从根对象出发在根对象的第一层孩子节点中标记所有可达的对象。 但是 G1 的垃圾收集器的 Initial Mark 阶段是跟 minor gc 一同发生的。也就是说在 G1 中你不用像在 CMS 那样单独暂停应用程序的执行来运行 Initial Mark 阶段而是在 G1 触发 minor gc 的时候一并将年老代上的 Initial Mark 给做了。并发标记(Concurrent Mark)阶段 在这个阶段 G1 做的事情跟 CMS 一样。但 G1 同时还多做了一件事情就是如果在 Concurrent Mark 阶段中发现哪些 Tenured region 中对象的存活率很小或者基本没有对象存活那么 G1 就会在这个阶段将其回收掉而不用等到后面的clean up 阶段。这也是 Garbage First 名字的由来。同时,在该阶段G1 会计算每个 region的对象存活率方便后面的 clean up 阶段使用 。最终标记( CMS 中的 Remark 阶段) 在这个阶段 G1 做的事情跟 CMS 一样, 但是采用的算法不同G1采用一种叫做 SATB(snapshot-at-the-begining) 的算法能够在 Remark 阶段更快的标记可达对象。筛选回收(Clean up/Copy)阶段 在G1中没有 CMS 中对应的 Sweep 阶段。相反 它有一个 Clean up/Copy 阶段在这个阶段中,G1 会挑选出那些对象存活率低的 region 进行回收这个阶段也是和 minor gc 一同发生的,如下图所示 G1Garbage-First是一款面向服务端应用的垃圾收集器。HotSpot 开发团队赋予它的使命是未来可以替换掉JDK 1.5中发布的 CMS 收集器。 如果你的应用追求低停顿G1 可以作为选择如果你的应用追求吞吐量G1并不带来特别明显的好处。 总结一个对象的一生 一个对象的一生我是一个普通的 Java 对象我出生在 Eden 区在 Eden 区我还看到和我长的很像的小兄弟我们在 Eden 区中玩了挺长时间。有一天 Eden 区中的人实在是太多了我就被迫去了 Survivor 区的 “From” 区S0 区自从去了 Survivor 区我就开始漂了有时候在 Survivor 的 “From” 区有时候在 Survivor 的 “To” 区S1 区居无定所。直到我 18 岁的时候爸爸说我成人了该去社会上闯闯了。于是我就去了年老代那边年老代里人很多并且年龄都挺大的我在这里也认识了很多人。在老年代里我生活了很多年每次GC加一岁然后被回收了。
http://www.w-s-a.com/news/131673/

相关文章:

  • 网站维护工程师代写文章兼职
  • 贵州城乡和建设厅网站企业网站备案名称窍门
  • .cc后缀网站湛江霞山
  • 青岛制作网站软件ui设计培训哪里好
  • 网站建设的构思环保公司宣传册设计样本
  • 如何做微网站网站和网店的区别
  • 免费下载建设银行官方网站下载天河区做网站
  • 中文网站建设开发北京网站建设公司升上去
  • 邯郸网站设计 贝壳下拉服务器绑定网站打不开
  • 重庆网站建设帝玖科技手机网站建设价钱是多少
  • 广西建设厅网站行业网学新媒体运营要多少钱
  • 石家庄个人建站网站策划门户网什么意思
  • 沈阳市浑南区城乡建设局网站wordpress 批量打印
  • 网站建设都需学哪些天津网站建设交易
  • 公司网站空间家装室内设计
  • 一个考试网站怎么做品牌建设10阶梯
  • 网站建设网站设计广东双语网站建设多少钱
  • 临时手机号注册网站建筑效果图
  • wordpress网站是什么类似wordpress博客
  • 国际网站空间昆明做网站开发维护的公司
  • 建网站选号域名网站优化大赛
  • 师范街网站建设广告制作公司口号
  • 电子商务网站开发设计报告为什么wordpress主题中字体不统一
  • 百度站长快速收录网站建设完工确认书
  • 企业网站备案代理商建设工程施工合同2013
  • 要学做网站wordpress xss漏洞
  • 白云品牌型网站建设在网上做国际快递淘宝网站
  • 无锡网站建设方式推广软件赚钱的app
  • 如何控制一个网站软件开发wordpress教育插件
  • 网站开发属于软件开发类吗wordpress邮件失败