jvm垃圾回收策略

一、垃圾回收策略主要由:引用计数法,可达性分析

引用计数法

在对象中添加一个引用计数器,每当一个地方引用它时,计数器就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的

缺陷:循环引用的对象就不会被回收。A引用B,B引用A。

所以,Java虚拟机没有采用引用计数法。它采用的是可达性分析算法。

可达性分析

可达性分析又被成为“GC Roots”的对象作为起点;从起点向下搜索,所走过的路径称之为引用链,当一个对象到GC Roots没有任何引用链相连接,代表此对象不可达。

可达性分析就是JVM首先枚举根节点,找到一些为了保证程序能正常运行所必须要存活的对象,然后以这些对象为根,根据引用关系开始向下搜寻,存在直接或间接引用链的对象就存活,不存在引用链的对象就回收。

那么在java可以作为GC Roots的对象可以是那些:

1、方法区静态属性引用的对象
全局对象的一种,Class对象本身很难被回收,回收的条件非常苛刻,只要Class对象不被回收,静态成员就不能被回收。

2、方法区常量池引用的对象
也属于全局对象,例如字符串常量池,常量本身初始化后不会再改变,因此作为GC Roots也是合理的。

3、在虚拟机栈中引用的对象,

例如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。
 

4、JNI本地方法栈中引用的对象
和上一条本质相同,无非是一个是Java方法栈中的变量引用,一个是native方法(C、C++)方法栈中的变量引用。

5、被同步锁持有的对象
被synchronized锁住的对象也是绝对不能回收的,当前有线程持有对象锁呢,GC如果回收了对象,锁不就失效
 

二、垃圾回收经典算法

1.标记清除法

在gc时候,首先扫描时对需要清理的无用对象进行标记,然后将这些对象直接清理。

缺点:内存碎片,因为物理上的不连续,如果清理了两个1lkb的对象,再添加一个2kb的对象,是无法放入这两个位置的。

2.标记整理法

标记整理算法就是在标记清除算法的基础上多加一个整理的过程,把空闲的空间进行上移,从而解决内存碎片的问题。

缺点:每一次垃圾清除都要频繁的移动存活对象,效率十分低下。

3.复制算法

复制算法是将空间一分为二,在清理时,将需要保留的对象复制到第二块区域上,复制的时候直接紧凑排列,然后把原来的一块区域清空。

缺点:空间变小,每次需要移动存活的对象,效率低下。

4.分代算法

整个过程大致分为以下几个步骤:

(1)当 Eden 满了后,进行 Minor GC,将需要保存的数据复制到 S0 中;

(2)然后清空 Eden 和 S1 区域,需要保留的对象目前在 S0 中;

(3)下一次当 Eden 满了后,进行Minor GC,将原来 S0 存在的数据复制到S1中,将 Eden 中需要保存的数据也复制到 S1 中;

(4)清空 Eden 和 S0 区域,需要保存的对象目前都在 S1 中;

(5)Eden+S0 复制到 S1;

(6)Eden+S1 复制到 S0;

(7)Eden+S0 复制到 S1;

周而复始...

三、垃圾回收器

1.serial收集器:

单线程收集器,在进行垃圾回收时,他会持有所有的应用程序线程,冻结所有应用程序线程,使用单个垃圾回收线程来进行垃圾回收。回收时间100ms左右,回收新生代

新生代采用复制算法,老年采用整理算法,STW。

2.Serial-Old收集器:

单线程收集器,和serial收集器搭配使用,他针对的是老年代

3.ParallelNew收集器

Serial收集器的多线程版本,与CMS垃圾回收器通常一起使用。

收集算法:新生代采用复制算法,老年代采用标记-整理算法。

4.Parallel scavenge收集器

多线程收集器

其它垃圾回收器关注的是缩短垃圾回收对用户线程的缩短时间。而该垃圾回收器关注的是吞吐量(缩短用户停顿时间对那些高交互性比如web项目看中的)

新生代采用复制算法,老年代采用整理算法

5.Parallel Old收集器

Parallel Scavenge的老年代版本,和Parallel Scavenge一起使用,算法是标记整理算法

6.CMS收集器

收集算法:采用标记-删除算法,只应用于老年代。

一种以获取最短回收停顿时间为目标的收集器。基于标记清除算法。整个过程分为四步:

(1)初始标记:只标记根节点直接关联的引用对象,需要暂停用户线程(时间短);

(2)并发标记:标记其他引用对象,可以跟用户线程并发同时执行

(3)重新标记:暂停用户线程,对并发标记期间新增加的引用关系变化再次标记(时间短);

(4)并发清除:跟用户线程并发进行。嗷嗷

缺点:

并发标记和并发清除时会和用户线程竞争资源。

无法清除浮动垃圾(由于用户线程还在执行,所以要预留一定空间给用户线程使用,所以一定不能在老年代已经占用100%情况下在进行垃圾回收)

内存碎片

7.G1收集器

采用标记整理算法,

可预测停顿(使用者明确指定一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒),

其它垃圾收集器都是整个新生代或者老年代。G1不是这样,它将java堆划分陈多个大小相等的独立区域。虽然还保留新生代老年代的概念。但是新生代,老年代不再是物理隔阂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值