jvm学习总结-垃圾回收

针对垃圾回收本文将从下面四个个方面进行总结:
1.对象存活判定
2.对象分代
3.垃圾回收算法
4.jvm 主流垃圾回收器简介
注:本文中提及的对象没有特殊说明一律值得是堆中的对象
一. 对象存活判定
判定对象存活的依据是是否有引用指向该对象。寻找对象的引用有两种方式:引用计数法和可达性判定

引用计数法:每个对象绑定一个引用计数器,当对象被引用计数器加一,当失去一个引用时,计数器减一。
计数法简单高效,当存在个严重的问题,当两个对象内部属性存在相互引用的情况下,两个对象的外部引用失效的时候,
内部之间的引用并没有进行释放,会导致属性对象无法释放。
    public static byte[] bytes = new byte[1024 * 1024 * 2]

 static class Score {
        public Student student;
        public String subject;
        public int score;
    }

    static class Student {
        public String name;
        public Score score;
    }

    public static void main(String[] args) {
        Student student = new Student();
        Score score = new Score();

        student.name = "Tom";
        student.score = score;

        score.score = 1;
        score.subject = "chinese";
        score.student = student;

        score = null;
        student = null;

        //这个位置会回收 做实验需要预先将jvm 的-Xms 定为2M
        System.gc();

    }
可达性判定以GC Root为根节点进行引用遍历,然后将无法到达的对象设置上回收标识。
可作为GC Root的有以下四种:
1.虚拟机栈中引用的对象
2.方法区中的静态引用的对象
3.方法区中的常量引用的对象
4.native 方法中引用的对象
与引用基数方法相比在遍历的过程中可能会相对耗时,当时回收的效果更好。

二. 对象分代
对象在堆中会根据年龄等因素分成两部分存储:新生代和老年代,空间配比有1:3
对象通常都是在新生代Edge中诞生(这个部分会在后边的回收算法中讲解),经历过一次minor gc 并且存活后便增长一岁,当年龄达到标准的时候会晋升为老年代。
还有两种例外:
1.当创建一个需要连续空间的大对象的时候,该对象会直接晋升为老年代,
2.动态对象年龄判断,当survivor中的处于同一年龄的对象所占用的空间超过50%的时候,年龄大于它的都将被晋升为老年代。

三.垃圾回收算法
垃圾回收算法有三种:标记-清除,复制和标记整理。
标记-清除:分为两个步骤,首先根据可达性判定,将要回收的对象标记,最后将标记后的对象回收。
存在的问题是会产生大量的内存碎片。
复制算法:将内存一分为二,在进行回收时,将from中存活的对象复制到to中,接着清空from。借鉴于这种思想,jvm的复制算法将新生代堆区域划分为一个edge,两个survivor(from, to),在进行回收的时候将edge和survivor-from 中存活的对象复制到survivor-to中,将to变为from, from变为to。这个可以通过老年代做分配担保(Handle Promotion) 来调整survivor的个数,感兴趣的同学可以自行学习下。
标记-整理:分为连个步骤,首先根据可达性判定,将要回收的对象标记,然后将所有存活的对象移动到堆一端,然后将边界外的区域回收。

四.jvm当前主流垃圾回收器
young generation(复制算法)
Serial:单线程回收
ParNew:多线程回收
Parallel Scavenge:多线程高吞吐回收 适用于后台计算服务

Tenured generation:
Serial Old: 单线程 标记整理
Parallel Old:多线程 标记整理
CMS(Concurrent Mark Sweep):基于标记清除算法实现,主要目的是缩短gc停顿时间。
主要分为四个步骤:
1.初始标记(initial mark):寻找所有的GC Root, 需要STW。
2.并发标记(concurrent mark):GC Root Tracking, 与用户进程并发执行。
3.重新标记(remark): 重新标记在并发标记过程中,由于用户进程运行所导致的引用变化。STW
4.并发清除(concurrent sweep):清除无用对象,与用户进程并发。
CMS有三个明显的缺点:
1.对于cpu资源敏感,因为并发标记和并发清除是和用户进程并发执行的,会消耗cpu资源,导致用户进程运行效率降低。
2.无法处理浮动垃圾,浮动垃圾是指在并发清除过程中,有用户进程产生的新垃圾,还有在收集的过程中用户进行也在运行,所以不能再空间呗用没了,再进行收集,目前在空间使用率超过92%的时候开始清理,在清理失败的时候会调用 Serial Old 来进行Full Gc。
3.由于使用的是标记清除,所以会产生内存碎片,所以在进行一定次数后CMS要进行一次Full Gc 对内存碎片进行清理。

这是本人学习周志明老师的《深入理解Java虚拟机-jvm垃圾回收机制》的小结笔记,如有错误的理解 还望大家指摘。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值