今天不是给你们介绍对象的,给你们介绍下垃圾,由于垃圾会霸占内存,需清理之,今天咱们聊聊JVM用什么方式回收垃圾的!先上图吧,咱们看看对象的生命周期。算法
先解释几个名词:微信
新生的对象都在eden区,当eden区满时容纳不了大的对象,会触发GC,若是对象还活着,小对象进入From区或者是to区,这两块区域有一块是空的,假设如今装对象是from区,那么,当GC后from区全部对象会复制到to区,而且清空from区域,存活对象年纪会增大一岁,当对象到达必定年纪以后,就会进入老年代了。若是对象比较大,Surviror装不下,会直接进入老年代,若是老年代也装不下,会报错:堆内存溢出。ide
简单介绍垃圾生命周期后,咱们看看垃圾清理算法。优化
引用计数法怎么判断一个对象是垃圾?就看是否有引用指向该对象。引用计数法表示若是一个对象有1个引用计数器就是1,2个引用计算器是2,若是没有引用,计数器为0,也就是垃圾对象。缺点是对象相互引用,对象没法回收。画图举个简单案例。spa
如上图代码:teacher持自身引用同时持有student的引用,计数器为2,student持自身引用同时持有teacher的引用,计数器为2,这叫相互引用,最终致使teacher或者student对象都没法被回收。因此如今垃圾回收器通常不采用引用计数法。线程
标记-清除分两步,GC线程先标记可达对象,当发生GC时,清除不可达对象。缺点是回收后内存碎片。对象
如上图,咱们知道分配内存都是连续的,垃圾对象回收后,内存很不规则,不利于内存使用效率。垃圾对象是不可达的?那什么叫可达对象呢,什么叫不可达对象呢?blog
理论性的东西仍是比较难理解,咱们画图表示下。生命周期
假设:new Object()对应的堆地址是0xJL。内存
Object object = new Object(); 栈object引用指向new Object()对应的0xJL地址,new Object()对象可达,其中object就叫作根对象。
object = null; 告诉gc线程,没有引用指向0xJL了,那这块内存就有可能被标记为垃圾对象。
复制算法须要将一块空白的内存一分为二,GC后,将可达对象所有移动到另外一块内存。新生代对象朝生夕死,GC后将活着的对象移动到另外一块空内存,并将当前使用的内存清空。每次GC,循环往复。
如上图:新生代采用复制算法,GC回收前使用from区域,GC后使用to内存区域。
标记整理算法基于标记清除算法作了必定优化,gc线程首先从根节点开始标记可达对象,并将可达对象压缩到内存顶部,最后清除边界区域,老年代对象生命周期长,比较适用于标记整理算法。
如上图:当老年代满了,会触发Full GC,将内存压缩整理。
画图解释了几种GC算法的含义和缺点,但愿对你有帮助,喜欢的请点赞加关注哦。点关注,不迷路,我是【叫练】公众号,微信号【jiaolian123abc】边叫边练。