概述
1、如何判断是否是要回收的对象?
1)引用计数算法:给对象添加一个计数器,每当有一个引用它时,计数器值加1;当引用失效时,计数器值减1。当计数器减为0时,说明该对象不能再被使用,此时该对象就可以被回收。
缺点:当有循环引用时,会一直得不到回收,例如变量a和变量b之间互相引用,形成循环引用。
2)可达性分析算法:通过一系列的称为“GC Roots”的对象为起点,从这些起点遍历,走过的路径称为引用链(Reference Chain)。当一个对象无法通过引用链到达时,该对象就是可被回收的。
补充:在Java语言中,可被当做GC Roots的对象包括:
1)虚拟机栈(栈帧中的本地变量表)中引用的对象;
2)方法区中类静态属性引用的对象;
3)方法区中常量引用的对象
2、垃圾回收算法
1)标记-清除算法(Mark-Sweep):两个阶段,“标记”和“清除”:首先标记出所有需要回收的对象,在标记完后统一回收所有被标记的对象。
缺点:标记和清除的效率都不高;多次标记清除后,会产生较多的不连续的内存碎片,导致在大的对象到来时,无法找到足够的连续内存而导致垃圾收集。
2)复制算法(Copying):将内存分为大小一样的两块,每次只是用其中一块,当使用中的这块内存存不下对象时,会发生复制。将可用对象复制到另一个空闲内存上(顺序存放),再将之前的内存中的对象全部清除。
缺点:内存利用率不到一半,太浪费;在对象存活率高的时候,效率明显下降。
3)标记-整理算法(Mark-Compact):类似于标记-清除算法,不同的是不直接清除可回收对象,而是将可用对象都移动到一端,然后将其它部分存在的可回收对象清除。
4)分代收集算法(Generational Collection):根据对象存活周期将内存分为不同的几块。例如Java中,堆被分为新生代和老生代,新生代采用上面的复制算法,老生代采用上面的标记-清理算法或者标记-整理算法。
3、扩展
1)垃圾收集器关注的是Java的堆内存
2)虚拟内存技术:在内存使用不足时,可以将不常用的数据存储到磁盘中,待到使用到这些数据时,再从磁盘中读取。这时,就将使用的磁盘当成内存看待。
3)新生代中对象的特点:IBM研究发现,新生代中的对象98%是要被回收的,为此将内存空间划分为8:1:1,8为Eden(伊甸园区),1为Survivor(幸存区)。
在使用时,只是使用其中的Eden和一个Survivor,当发生回收时,将可用对象复制到那块空闲的Survivor,完成后清理Eden和之前使用的Survivor。这样内存浪费的就较少。
4)新生代/老生代:一般刚创建出来的对象是放入新生代中,在GC15次(默认次数)后,还没有被回收的对象,就会进入老生代。
发生了老生代的内存担保机制(新生代存储不下,就可能存储到老生代),也会将对象放入老生代
5)新生代中的对象在每次GC时,会有大量的对象被回收;而老生代中对象的存活率较高,并且较少发生GC。
新生代的GC:Minor GC
老生代的GC:Major GC(Full GC,即新生代也会被触发GC)
6)GC调优的目的是减少Full GC
4、GC收集器
GC收集器是内存回收的具体实现。
新生代收集器
1)Serial收集器:单线程,在进行收集时,必须停止其它线程;
2)ParNew收集器:多线程的Serial收集器,使用复制算法,也必须停止其它线程后才进行收集。除了Serial外,只有ParNew可以与CMS一起配合使用;
3)Parallel Scavenge收集器:并行的收集器,但关注点是:吞吐量(Throughput),而其它收集器关注的是减少用户的停顿时间;最大特点以下介绍的GC自适应的调节策略
扩展:GC自适应的调节策略(GC Ergonomics):通过设定参数,可以让虚拟机自己根据系统运行情况动态的调整内存使用策略,达到动态的提供合适的停顿时间或最大的吞吐量。
老生代收集器
1)Parallel Old收集器:Parallel Scavenge的老生代版本,使用的是标记-整理算法;
2)CMS(Concurrent Mark Sweep)收集器:一种以获取最短回收停顿时间的为目标的收集器。基于标记-清理算法。整个收集过程包括四个:初始标记(CMS initial mark)、并发标记(CMS concurrent mark)、重新标记(CMS remark)、并发清除(CMS concurrent sweep)。
其中初始标记、重新标记需要停顿用户线程,但停顿时间很短
GI收集器:没有区分新旧代,而是将整个堆分为若干个小区块,其中新建对象在Eden Space中;回收后幸存对象在Survivor Space中;多次回收依旧存活的对象在Old Generation中。
最后
以上就是沉默音响为你收集整理的Java中的GC(Garbage Collection)的全部内容,希望文章能够帮你解决Java中的GC(Garbage Collection)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复