垃圾收集器和内存分配策略

引用计数法

策略:给对象添加一个引用计数器,当有一个地方引用到它时,计数器加1,引用失效的时候计数器减1,
当计数器的值是0的时候代表这个对象不需要使用可以被回收了。
问题:难以解决循环引用的问题。

可达性分析算法

策略:根据一系列称为"GC Roots"的对象作为起点,从这些节点向下搜索,搜索走过的所有的路径称为
引用链。当一个对象到GC Root没有任何引用链相连的时候,证明此对象是不可用的。
那么哪些对象可以作为GC Root呢?
    1.虚拟机栈(栈帧中的本地变量表)中引用的对象
    2.方法区中的静态属性引用的对象
    3.方法区中常量引用的对象
    4.本地方法栈中JNI引用的对象。

引用:
    1.强引用。new这类的引用,只要强引用在,垃圾回收器就不会回收掉被引用的对象。
    2.软引用。还有用但并非必须的对象。对于这些对象,在系统将要发生内存溢出之前,将会把这些对象
    列进回收范围之中进行第二次回收。如果这次回收还是没有足够内存。
    3.弱引用。非必需对象,你软引用的强度更弱。只能存活到下次垃圾回收之前。
    4.虚引用。幽灵引用或者幻影引用。最弱的引用关系。
        唯一设置目的是:当该对象被垃圾回收时能收到一个系统通知。

垃圾收集算法

1.标记清除算法
    标记出所有需要回收的对象(标记方法GC Root),然后清理。
    问题:标记的过程和清除的过程效率都不高,同时清除后可能出现大量的闲碎空间。
        闲碎空间的问题就是之后无法找到一个大的连续的内存给大对象分配一个空间,从而可能多一次GC。
2.复制算法
    解决上面出现的效率问题。
    可用内存分为相等的两块。每次使用一块,GC之后将还存活的复制到另一块。
    好处:每次都是对半区进行内存回收,没有内存碎片的问题,简单高效。
    问题:内存的使用率变为一半,代价高。
    现代虚拟机都是用这种方式收集新生代。因为大多数对象朝生夕死。所有比列
    Eden:Survivor = 8:1;Edeny一块,Survivor两块。
    Eden不够的时候需要去老年代分配担保一点出来。
3.标记整理算法
    解决老年代的问题。
    前面也是标记,然后是把存活的对象往一端移动,然后把边界以外的都清楚掉。
4.分代收集算法
    新生代由于存活对象少,复制算法。
    老年代由于存活的多。标记清楚或者标记整理算法。

垃圾收集器

1.Serial收集器
    单线程收集器。单线程意味着不仅仅是一个CPU或者一条收集线程去完成垃圾垃
    圾收集的工作,更意味着垃圾收集的同时,必须停止其他所有的线程工作。Stop the World。
    目前仍然是Client模式下的默认的新生代的垃圾收集器。
    优点:简单高效。没有线程交互的开销。
2.ParNew收集器
    它是Serial收集器的多线程版本。Server模式下的新生代收集器。
3.Parallel Scavenge收集器
    新生代收集器,也是复制算法。这个收集器的关注点在于吞吐量(cpu运行用户代码/cpu总消耗时间)。
4.Serial Old收集器
    单线程的老年代收集器,使用标记-整理算法。
    Client模式。
5.Parallel Old收集器
    多线程的老年代收集器,标志-整理算法。吞吐量优先的收集器。
6.CMS收集器
    基于标记清除算法。
    并发收集,低停顿。
    四个步骤:
        初始标记,并发标记,重新标记,并发清除。
    初始标记和重新标记还是要stop the world。
    初始标记就是标记GC root能直接关联到的对象。
    并发标记就是执行GC root Tracing的过程。重新标记是修正并发标记期间用户程序继续运行产生的变动。
    CMS收集器对cpu资源敏感
    无法处理浮动垃圾。
    如何解决碎片的?CMS收集器提供了一个UseCMSCompactAtFullCollection的开关,
    用于在cms收集器顶不住进行FullGC的时候开启内存碎片的整理过程。

7.G1收集器    
0%