垃圾收集管理器 GC

垃圾收集管理器 GC

      是jvm的一个后台线程,此线程完成的功能主要是收集堆空间中的没有引用的对象内存空间并释放空间

gc针对的是堆区,

在堆空间中创建的对象是创建在新生代中,

新生代区: young generation

      新生代分类:

      伊甸园区: Eden 所有的新创建的对象都放在此区中

      幸存区: Survivor 在Eden区中经过一个扫描,此对象还存在就把对象从Eden移动到此区中

      一个Eden区对应两个survivor区  8:1:1

      最后一个survivor是空闲的,是系统保留区

      老生代区: old generation

           在幸存区经过多次扫描的对象,还存在在幸存区,就把幸存区中的对象移动到老生代中,老生代扫描对象是否可用的频率远低于幸存区的扫描频率,如果在老生代中长时间存在的对象,建议程序员在写代码的时候把对象放在方法区,考虑对象的作用域空间

minor gc : 初代回收: 收集的是新生代的Eden区的空间

full GC : 完全回收,收集的是老生代的内存空间

  1. 要回收那些区域?

JVM内存模型中,有三个是不需要进行垃圾回收的: 程序计数器,JVM栈,本地方法栈.因为他们的生命周期是和线程同步的,随着线程的销毁,他们占用的内存会自动释放,所以只有方法区和堆区需要进行GC

  1. 如何判断对象是否存活
    1. 引用计数法

引用计数法是垃圾收集器中的早期策略,在这种方法中,堆中的每一个对象实例都有一个引用计数,当一个对象被创建时,就将该对象分配给一个变量,该变量计数设置为1,当任何其他变量被赋值为这个对象的引用时,计数+1,(a=b,则引用的对象实例的计数器+1),但是当对象实例的某个引用超过了生命周期或者被设置成为一个新值时,对象实例的引用计数器-1,任何引用计数器为0的对象实例可以被当做垃圾收集,当一个对象实例被垃圾收集时,他引用的任何对象实例的引用计数器-1.

优点: 实现简单,判断效率高

缺点: 很难解决对象之间的相互循环引用,所以java语言并没有选用引用计数法管理内存

    1. 可达性分析算法(根搜索算法)

可达性分析算法是从离散数学中的图论引入的,程序吧所有的引用关系看做一张图,从一个节点GC Root开始,寻找对应的引用节点,找到这个节点后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕后,剩余的节点被认为是没有引用的节点,即无用的节点,无用的节点会被判定为可回收的对象

在java语言中,可以作为GC Roots的对象包括以下几种:

      1. java虚拟机栈引用的对象(栈帧中的本地变量表)
      2. 方法区中的类静态属性引用的对象
      3. 方法区中常量引用的对象
      4. 本地方法栈中JNI(Native方法)引用的对象
  1. 对象死亡(被回收)前的挣扎

通过可达性分析,那些不可达的对象并不是立即被销毁,他们还有被拯救的机会.如果要回收一个不可达的对象,要经过两次标记过程,首先是第一次标记,判断对象是否覆写了finalize方法,如果没有覆写,则直接进行第二次标记并且回收,如果对象在finalize()方法中重新与引用链建立了关联关系,那么将会逃离本次回收,继续存活

方法区中主要回收的内容有: 废弃常量和无用的类.对于废弃常量,也可以通过引用的可达性来判断,但是对于无用的类则需要同时满足以下三个条件:

  1. 该类的所有实例都已经被回收,java堆中不存在任何该类的实例
  2. 加载该类的ClassLoader已经被回收
  3. 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
  1. 常用的垃圾回收算法
    1. 标记-清除算法

标记清除算法采用从根集合(GC root)进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收,此算法一般没有虚拟机采用

优点:

  1. 解决了循环引用的问题
  2. 与复制算法相比,不需要对象移动,效率较高,而且不需要额外的空间

不足:

  1. 每个活跃的对象都要进行扫描,而且扫描两次,效率低,收集暂停的时间比较长
  2. 产生不连续的内存碎片

    1. 复制算法

将内存分成两块容量大小相等的区域,每次只使用其中一块,当这一块内存用完了,将所有存活的对象复制到另外一块内存空间,然后清除前一块的内存空间,这样不容易出现内存碎片的问题

      1. 复制的代价较高,所以适合新生代,因为新生代的对象存活率较低,需要复制的对象比较少,
      2. 需要双倍的内存空间,而且总有一块内存空闲,浪费空间

    1. 标记-整理算法

思想: 在完成标记之后,不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存.不会产生碎片,但是移动对象的成本较高

    1. 分代收集算法

分代收集算法是目前大部分JVM的垃圾收集器采用的算法.它的核心思想是根据对象的存活的生命周期将内存划分为若干个不同的区域.一般情况下将堆区划分为老年代,和新生代,在堆区之外还有一个代就是永久代(Permanet Generation),老年代的特点是每次垃圾收集时只有少数对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就根据不同代的特点采取最适合的收集算法,

内存被分为三个区域:新生代(Enden,from survivor space,to survivor space),老年代,永久代(方法区)

      1. 新生代的回收算法

包含有Enden,from survivor space,to survivor space,绝大多数新被创建的对象会被分配到这里,大部分对象创建之后很快变得不可达

        1. 所有新生成的对象首先都是放在新生代的,新生代的目标就是尽可能快速的收集掉那些生命周期短的对象
        2. 新生代内内存按照8:1:1的比例分为1个Eden区和两个survivor区,大部分对象在Eden中生成.回收时现将Eden区存活的对象复制到一个survivor区,然后清空Eden区,当这个survivor0区也存放满时,则将Eden区和survivor0区存活的对象复制到另一个survivor1区,清空Eden区和survivor0区,此时survivor是空的,然后将survivor0区和survivor1区交换,即保持survivor1区是空的,如此往复
        3. 当survivor1区不足以存放Eden和survivor0的存活对象时,就将存活对象直接放到老年代,若是老年代也满了就会触发一次Full GC,也就是新生代和老生代都进行回收
        4. 新生代发生的GC也叫Minor GC,发生频率比较高(不一定等Eden区满了才触发)
      1. 老年代的回收算法
        1. 在年轻代经历了N次垃圾回收之后仍然存活的对象,就会被放在老年代中,因此可以认为老年代中存放的都是生命周期比较长的对象
        2. 内存比新生代也大很多,当老年代内存满时触发Major GC即Full GC,FullGC发生的频率比较低,老年代对象存活的时间比较长,存活率比较高
      2. 永久代的回收算法

用于存放静态文件,如java类,方法等,持久代对垃圾回收没有显著影响,但那是有些可能动态生成或者调用一些Class例如Hibernate等,这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增加的类,持久代也称为方法区

  1. GC是什么时候触发的

由于对象进行了分代处理,因此垃圾回收区域,时间也不一样,GC有两种类型: Minor GC和 Full GC

    1. Minor GC

一般情况下,当新对象生成,并且在Eden申请空间失败后,就会触发Minor GC,清除非存活对象,并且把尚且存活的对象移动到survivor区,然后整理survivor的两个区.这种方式的GC是对年轻代的Eden区进行,不会影响到老年代.因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区域的GC 会比较频繁.因而,一般在这里需要使用速度快,效率高的算法,使Eden区能够尽快的空闲出来

    1. Full GC

对整个堆进行整理,包括Young,Tenured和Perm,Full GC 因为需要对整个堆进行回收,所以比Scavenge GC要慢,因此尽可能减少Full GC的次数.在JVM调优的过程中,很大一部分工作就是对于Full GC的调节,有如下原因可能导致Full GC:

  1. 老年代被写满
    1. 上一次GC之后Heap的各域分配策略动态变化
    2. System.gc()被显式调用
    3. 持久代被写满
  2. jvm查看gc的命令: jstat –gc 12538 5000 每隔5秒显示一次进程号为12538的java进程的GC情况
  3. 如果频繁老年代回收怎么分析解决

老年代存放的是经过几次回收仍然存在或者比较大的对象(这个大就要看是否设置了 –XX:PretenureSizeThreshold参数).检查程序中是否存在比较大的对象,或者这个参数设置是否合理

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值