java虚拟机垃圾收集

一.java内存模型

在java虚拟机中,内存大致分为线程私有区域和线程共享区域。
线程私有:1.虚拟机栈 2.本地方法栈 3.程序计数器
线程共享:1.方法区 2.堆
java虚拟机栈用于存储java方法的执行参数,每个方法执行时都会生成一个栈帧,包含有:局部变量,操作数栈,动态链接,方法出口等,每次方法执行完成后,栈帧就会出栈,所以内存的分配都是确定的且会自动销毁。
方法区和堆主要用于存储类文件,常量表,对象,数组等大小和数量不确定的数据,所以需要对应的内存管理机制。

垃圾收集内存模型:分代收集
年轻代:分为eden(80%),from(10%),to(10%)。from和to区的存在:1.eden区存活对象复制到to区,避免直接复制到老年代,增加full gc频率 2.分为from,to两个区域,方便在复制过程中处理内存碎片。
老年代:存储大对象或者长时间存活的对象。
持久代:hotspot vm独有,方法区的实现方式,jdk1.8之后替换为元空间(字符常量到java heap,主要使用堆外内存)。

TLAB: 线程本地分配内存,每个线程拥有TLAB,用于避免多线程冲突,提高对象分配效率。

逃逸分析和标量替换
逃逸分析:对象如果只在方法体中使用,就是未逃逸,在这种情况下可以考虑只在栈中为对象分配内存,及时销毁。
标量替换:在需要生成未逃逸的对象时,只生成它的成员变量。

二.标记方法

1.引用计数法(因循环引用而弃用)
2.可达性分析:从GC roots出发,遍历所有有引用的对象(广度优先遍历),清理不可达的对象。
gc roots:虚拟机栈中的引用对象;方法区中常量引用对象;方法区中静态引用的对象;本地方法栈中JNI引用的对象;活跃线程

引用类型:
强引用(一般新建对象时会存在的引用):存在强引用的对象不会被回收。
软引用(通过softReference建立):内存空间不足时回收。一般与referenceQueue联合使用,当引用对象被回收,则将软引用加入引用队列。适用场景:浏览器前进后退时根据内存使用情况确定是否保存之前的页面。
弱引用:发生垃圾回收时对只有弱引用的对象进行回收。
虚引用:任何时候都可能被回收。必须和一个引用队列联合使用,一般用于跟踪对象的垃圾回收过程。

三色标记法:垃圾收集器在进行可达性分析的时候,一般会STW(用户线程在safepoint暂停)避免枚举引用图时用户线程导致引用关系的变化。STW时间会随着对象数量增加而增加,为了降低停顿时间,后续垃圾收集器开始支持并发的垃圾收集过程。三色标记法解决了并发过程中的引用变化问题。
并发标记会产生浮动垃圾和对象消失问题:1.赋值器插入一条或者多条黑色对象到白色对象的新引用;2.赋值器删除了全部从灰色对象到该白色对象的直接或者间接引用。
原理:将引用图中的结点分为 白色(尚未被垃圾收集器访问);灰色(已经被访问,但是至少有一个引用未被访问);黑色(自己和所有的引用都已经被访问);

解决方案:1.增量更新:黑色对象要插入到白色对象的引用时,记录引用,并发扫描结束,以记录的引用关系中的黑色节点为根节点再扫描一次。
2.原始快照:灰色对象要删除到白色对象的引用时,记录引用,并发扫描结束再从灰色节点扫描一次。
发生时间:增量更新是写后屏障(类似aop切面),记录新增引用记录;原始快照是写前屏障,记录即将被删除的旧引用。

三.垃圾回收算法

1.标记-清除:标记对象,完成后统一回收;缺点是容易形成大量不连续的内存碎片,碎片太多容易导致后续无法分配空间给大对象而导致在空间足够的时候触发垃圾收集。
2.复制算法:将内存划分为两个部分,一次只使用其中一部分,当它空间不足时,将存活的对象复制到另一部分。新生代具体使用方法是分配为 eden和两个survivor(eden占80%,survivor占10%),每次只使用eden和一个survivor,存活对象复制到剩下的survivor和老年代。
3.标记-整理:标记对象,将存活对象移动到一端,清理掉端边界以外的内存。老年代一般使用标记-整理算法,不适用复制算法(1.复制算法不适用对象存活率高和大对象,需要多次的复制操作,效率低。2.复制算法需要额外的空间来存放无法被完全复制的对象。)
4.分代收集算法:根据对象存活周期将内存划分。新生代对象存活率低,用复制算法;老年代存活率高,没有额外担保空间,使用标记-整理算法。

四.垃圾收集器

1.serial:新生代;复制算法;串行收集,运行时会导致STW;特点是简单高效,主要适用于client端的简单桌面应用。
2.parNew:serial的多线程版本,其他性质相同。特点是可以配合CMS垃圾收集器。
3.parallel Scavenge:新生代;复制算法;并行多线程;特点是尽可能缩短垃圾收集时用户线程的停顿时间,达成可控制的吞吐量。

4.CMS:老年代+新生代;标记-清除;并发收集(初始标记,并发标记,重新标记,并发清理);低停顿,但是容易导致内存碎片
5.serial old:老年代,标记-整理算法;单线程回收
6.parallel old:老年代;标记-整理
7.g1:取代CMS;并行回收;内存分割为多个不连续的region;根据允许收集时间,优先回收价值最大的region;四种角色(eden,survivor,old,humongous);用于大内存,多处理器的服务端;rs记忆集记录region的引用和被引用,避免全局扫描;

parallel gc:parallel scavenge + serial old 或 parallel scavenge + parallel old
parallel scavenge 悲观策略:minor gc时,会将无法放在survivor的对象晋升到老年代,老年代无法存放则会触发full Gc,full gc会对年轻代进行一次minor gc。在这种情况下,一次minor gc会触发两次对年轻代的回收,为避免这种情况,选择了悲观策略。
实现:minor gc时,取出年轻代平均晋升大小和当前年轻代使用空间取最小值,如果这个值大于老年代剩余空间,则放弃minor gc,触发full gc。minor gc后,判断平均晋升大小,若大于old所剩空间,同样触发full gc。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值