• java对象和垃圾回收


    1、垃圾回收

    (1)哪些对象可以被回收

      答:如何判断哪些对象可以被回收?通常来说有两种算法:引用计数法 和 可达性分析法。引用计数法:给对象添加一个引用计数器,每当一个地方引用它时,计数器就+1,;当引用失效时,计数器就-1;任何时刻计数器为0的对象是不能再被使用的,即可回收的。但是,引用计数法存在一个BUG,就是当两个在其他地方无用的对象互相引用时,那么它们的引用计数器都为1,那么他们就会永远不能被回收。可达性分析法:通过一系列的被称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时(就是从GC Roots到这个对象不可达时),则证明这个对象是不可用的,可以被回收掉。可以作为GC Roots的对象包含以下几种:①虚拟机栈(栈帧中的本地变量表)中引用的对象②方法区中类静态属性引用的对象③方法区中常量引用的对象④本地方法栈中JNI(即Native方法)引用的对象。

    (2)什么时候回收

      答:当JVM无法为新对象分配内存时,就会触发GC操作。

    (3)如何回收

      答:常见的回收算法有以下几种:标记清除算法、复制算法、标记整理算法分代收集算法。

        (1)标记-清除算法:

          如它的名字一样,算法分为“标记” 和 “清除”两个阶段。首先标记出所有需要回收的对象,然后在标记完成后统一回收所有被标记的对象。标记-清除算法是最基础的收集算法,后续的收集算法都是在它的基础上改进完善而得到的。它的不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;第二个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致在程序运行过程中需要分配较大的对象时,因为无法招到足够的连续内存而不得不提前触发垃圾收集动作,如果程序中的大对象比较多,可能会导致JVM频繁的触发垃圾收集动作。

        (2)复制算法

          为了解决标记-清除算法的效率问题和内存碎片问题,复制算法产生了。复制算法将内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象 复制 到另一块内存,然后把已使用的这块内存整体一次清理掉。这样既提高了效率,也避免了空间碎片的产生。但是,这样却要牺牲掉一半的内存,代价未免太高了一些。但是,根据IBM公司的研究,新生代中的对象98%是朝生暮死的,所以不需要按照1:1的比例来划分内存空间。而是将内存空间划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中的一块Survivor,当回收时,将Eden和Survivor上还存活的对象全部 复制 另一块Survivor空间上,然后一次回收Eden和用过的Survivor空间。HotSpot虚拟机默认Eden和Survivor空间的大小比例是8:1:1,这样就只会浪费10%的内存空间,这个代价是可以接受的。

        (3)标记-整理算法

          复制算法在 对象存活率较高 的情况下需要进行大量的复制操作,而且如果每次回收时都有多余10%的对象存货,那么仅仅一块Survivor空间是不够用的,还需要依赖其他内存进行分配担保。这样效率就会变得很低。于是有人提出了另一种算法,就是 标记-整理 算法。它的标记过程与 标记-清除 算法一样,但是后续步骤不是直接对可回收对象直接进行回收清理,而是让所有的存活对象向一端移动,然后直接清理掉边界以外的内存。避免了空间碎片的产生,而且不需要浪费内存。

        (4)分代收集算法

          当前商业虚拟机都采用的是分代收集算法。分代收集算法并没有新的算法思想,只是根据对象存活周期的不同将内存划分为几块。一般是把java堆分为新生代和老年代,根据各个年代的特点采用最适当的垃圾收集算法。在新生代中,每次都有大量的对象死去(需要被回收),就选用复制算法,这样只需要付出少量存活对象的复制成本就可以完成收集和清理;而老年代中对象存活率较高且没有额外空间对它进行空间分配担保,就必须要使用 标记-清理 或者 标记-清除 算法来完成。

  • 相关阅读:
    20155338 2016-2017-2 《Java程序设计》第4周学习总结
    20155338 2016-2017-2 《Java程序设计》第3周学习总结
    20155338 2006-2007-2 《Java程序设计》第2周学习总结
    20155316 实验三《敏捷开发与XP实践》实验报告
    20155316 2016-2017-2 《Java程序设计》第10周学习总结
    20155316 2016-2017-2 《Java程序设计》第9周学习总结
    20155316 实验二《Java面向对象程序设计》实验报告
    20155316 2016-2017-2 《Java程序设计》第8周学习总结
    20155316 实验一《Java开发环境的熟悉》实验报告
    20155316 2016-2017-2 《Java程序设计》第7周学习总结
  • 原文地址:https://www.cnblogs.com/yangwanhao/p/11373643.html
Copyright © 2020-2023  润新知