JVM学习——gc回收机制

Posted by Csming on 2017-03-12

最近复习Java基础细节的时候看Thking in Java;书上有提到两种垃圾回收机制,“停止-复制”、“标记-清扫”;


  • **停止-复制:**将暂停程序的运行,然后将所有存活的对象从当前堆复制到另一个堆,而没有被复制的对象都是垃圾;当对象被复制到新堆时,它们是一个挨着一个的,所以新堆保持紧凑排列;然后就可以直接分配新空间了

  • **标记-清扫:**从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象;每找到一个存活对象,就会给对象一个标记,这个过程不会回收任何对象;当全部标记工作完成时,清扫动作开始;

**JVM采用自适应的垃圾回收机制:**JVM会进行监视,若所有对象都很稳定,垃圾回收器效率降低,就切换为“标记-清扫”模式;当JVM跟踪“标记-清扫”的效果,发现堆空间有很多碎片时,就会切换回“停止-复制”方式;

垃圾回收

垃圾回收又称gc,gc是运行在JVM中,回收应用程序中创建的无用的对象

什么是垃圾

垃圾就是没有任何价值,没有任何用的东西

如何判断垃圾

Java通过引用于对象进行关联,操作一个对象;被引用相关联的就不是垃圾;
那么没有引用指向这个对象,也就是说该对象已经没有任何引用,那么它就是垃圾;

判定“垃圾”的方法

  • 引用计数算法
    1.给对象添加计数器,如果引用,计数器+1;
    2.引用失效,则计数器-1;
    3.任何时刻计数器为0的对象不能再使用了

  • 根搜索法
    1.gc roots为起点,从这个节点开始向下搜索
    2.所走过的路径,用Wie引用链
    3.对象到gc roots没有任何链相连,对象不可用

常见的垃圾回收场景

  • 对象被赋值null,或手动释放

  • 弱引用
    若一个对象具有弱引用,在GC线程扫描内存区域的过程中,不管当前内存空间足够与否,都会回收内存,使用弱引用 构建非敏感数据的缓存。

弱引用申明:

1
WeakReferenceweakReference=new WeakReference(new User());
  • 虚引用
    如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收,虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列联合使用,虚引用主要用来跟踪对象 被垃圾回收的活动。

虚引用申明:

1
PhantomReference phantomReference=new PhantomReference(new User(),new ReferenceQueue());

gc回收器

  • gc的划分
    新域:储存所有生成的对象
    旧域:新域中的对象经过几次gc之后,没有被回收,进入旧域中
    永久域:存储类和方法对象,从配置的角度看,这个域是独立的,不包括在JVM堆内。默认为4M。

  • 新域
    新域中会被分为三个部分:一个缓冲区,两个休闲区
    新域中,产生的大部分对象都会被回收,少部分进入旧域

1.第一个部分叫做Eden(伊甸园)
2.辅助的生成空间(幼儿园)
A空间…
B空间…

  • 旧域
    旧域也被分为几部分,但是旧域中,存活的对象就比较多,所以,旧域中一般回收的对象会比较少

  • 永久域
    一路下来,如果对象还未被回收,那么久会流入永久域中存起来,并不是对象到这里了,gc就不去回收了,只是gc不太会去回收这里面的对象。

垃圾回收器算法

  • Mark-Sweep算法

  • Copying算法

  • **Mark-Compact算法:**为了解决空间浪费问题而改进的算法;
    1.标记阶段和Mark-Sweep一样
    2.完成标记后,不直接清除回收对象,将对象移向一段
    3.清理边界内存

  • **Generational Collection算法(分代收集法):**根据存活的生命周期分为了:新生代,老年代和永久代,也就是新区,旧区和永久区

1.根据存活的生命周期将内存分为若干个区:新生代和老年代和永久代
2.新生代:每次都回收大量对象——>Copying复制法
3.老年代:每次都回收少量对象——>Mark-Compact法
4.永久代:存储class类,常量,方法描述:回收废弃常量和无用类

看了CSDN上曾淘前辈的这篇博文后,我想分代收集法应该就是Thking in Java中所描述的自适应方法


出处:http://blog.csdn.net/u011546655/article/details/52186044
资料借鉴:《Thking in Java》