您的位置:首页 > 编程语言 > Java开发

深入理解Java虚拟机-垃圾收集

2018-03-31 15:06 232 查看
1.如何判定对象为垃圾对象
    (1)引用计数法
在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值加一,当引用失效的时候,计数器的值减一,不过存在循环引用问题
    (2)可达性分析法
定义GC root,一直从GC root向下寻找,如果不可达则是垃圾对象。虚拟机栈,方法区类属性所引用的对象,方法区中常量所引用的对象,本地方法栈中引用的对象可以作为GC Roots的对象。

2.如何回收
    (1)引用计数
当对象引用计数为0时,回收对象,但存在循环引用问题。
    (2)标记-清除算法
从根对象开始标记,可达到的标记为可达对象,没有被标记的被清除。效率问题,标记和清除两个阶段会存在效率问题。空间问题,存在内存碎片。
    (3)复制算法
堆会被分成两部分,新生代和老年代,新生代又会分成Eden,Survivor,Tenured Gen区域。在Survivor中被标记为存活对象的会从Survivor的from区复制到to区,在from区的垃圾对象被清除。下次垃圾回收存活对象又会从from区复制到to区。由此可见,每次只能利用一半内存,所以复制算法存在内存浪费问题。
    (4)标记-整理算法
主要用于老年代垃圾回收。将标记为存活的对象移动到内存的一端,清理边界外的内存,将未被标记的对象回收。
    (5)分代收集
根据内存分代选择不同的回收算法,新生代选择复制算法,老年代选择标记-整理算法。因为老年代通常是一些大对象复制算法的成本比较高。
3.常见的垃圾回收器
    从不同的角度可以将垃圾收集器分成不同的类别。按线程数分为串行垃圾回收器,并行垃圾回收器。按工作模式分为并发垃圾回收器和独占垃圾回收器。按碎片处理分为非压缩垃圾回收器和压缩垃圾回收器。按分代分为新生代垃圾回收器和老年代垃圾回收器。

    (1)Serial
        最基本,发展最悠久的,单线程独占式垃圾收集器。在运行时,应用程序的所有线程都停止工作,进行等待,即“Stop the World”
                                


    (2)Parnew
        多个线程进行垃圾收集。
                                 


    (3)CMS(Concurrent Mark Sweep)
工作过程:初始标记,并发标记,重新标记,并发清理
优点:并发收集,低停顿
缺点:占用大量的CPU资源;无法处理浮动垃圾,即进行一次垃圾回收后应用程序线程又产生的垃圾;出现Concurrent Mode Failure,即CMS回收过程中,应该确保应用程序有足够的内存可用,如果应用程序的内存使用率增长很快,在CMS执行的过程中,已经出现了内存不足的情况,此时CMS回收就会失败,JVM将启动老年代串行收集器进行垃圾回收。如果这样,停顿时间会更长。因为CMS基于标记-清除算法,所以存在空间碎片问题。
         


    (4)G1
优点:并行和并发,充分利用多核cpu优势,缩短停顿时间;分代收集,分为不同的内存区域进行回收;空间整合;可预测的停顿
步骤:初始标记;并发标记;最终标记;筛选回收(Remember Set记录了一个区域的对象对另一个区域对象的引用)
与cms比较:因为采用标记-压缩算法不存在空间碎片问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: