JVM内存回收

一、概述

正所谓垃圾收集,即内存回收,将一些用不到的对象等从内存中去掉,使内存充足,而不至于OOM。那就自然面临下面的三个问题?

  1. 哪些内存需要回收?
  2. 何时进行回收?
  3. 如何进行回收?

二、如何判断对象已死?(不再使用该对象)

只有先判断出该对象是否已死,才能确定是否对该对象占有的内存进行回收。

1、引用计数算法

对每个对象都有一个引用计数器,用来记录该对象被引用的次数。缺点就是很难解决对象之间的相互循环引用问题。

2、可达性分析算法

虚拟机会维持一个从根节点为GC Roots的对象引用树,当对象没有在该树上时则可回收。

三、如何回收(垃圾收集算法)

1、标记-清除算法

对可回收的对象进行标记,然后统一进行回收。
缺点:导致回收完之后内存不连续,以致于后续存储大对象内存不足

2、复制算法(新生代)

将内存分为两块AB,一块A存储,一块B空闲,当A空间不足进行垃圾回收时,将A中活跃对象直接复制到B,然后将A清空,解决了内存不连续问题。
缺点:一分为二,内存的使用率只有50%,直接造成内存浪费。并且对于活跃对象比较多的进行GC后复制,耗时耗CPU。

复制算法改进版

将新生代内存分为3块,eden,survivor1,survivor2。比例为8:1:1(默认可改)。因为研究表明新生代98%对象都是“朝生夕死”,真正能持续存活的比较少。
eden和survivor1 为新的对象分配内存,survivor2 存放MinorGC(对新生代的GC称呼)后存活下来的对象,survivor1和eden则被清空,即survivor1和survivor2轮流空闲,因为eden和一块survivor始终在使用,所以实际上浪费的内存只占10%。
当survivor内存不足以存放MonirGC存活下的对象,则向老年代进行分配担保(handle promotion),即将survivor对象放入老年代中。

3、 标记-整理算法(老年代)

因为老年代中对象存活时间比较长,所以不适合于复制算法。
标记-整理算法实质上是标记-清除算法的改进版,过程与之一模一样,只是后续会对回收后的内存进行整理而使其变成连续的块内存。

4、分代收集算法(当前)

根据对象的存活周期将内存划分为几块,如将java堆划分为新生代和老年代,每一个划分实行不同的垃圾收集算法。
新生代对象存活时间短,GC后存活对象少,则复制到survivor的对象也比较少,所以选用复制算法。
老年代存活率高,没有额外的空间进行担保,所以必须使用标记算法。

四、垃圾收集器(对上述算法的具体实现)

1、Serial 收集器

一个单线程进行垃圾回收,并且在回收的时候,暂停其他所有工作线程,直到收集结束。俗称Stop The World。
目前是虚拟机Client模式下的默认收集器

2、ParNew收集器

于Serial收集器类似,不同处在于,其是所线程进行垃圾回收。
是虚拟机在Server模式运行下首选的收集器,因为只有 ParNew收集器才能与CMS收集器配合工作。

3、Parallel Scavenge收集器(新生代)

新生代,复制算法,并行多线程。
于ParNew不同在于,其目标主要用来控制吞吐量
吞吐量 = 运行用户代码时间/(运行用户代码时间+垃圾收集时间)
如总共运行100分钟,其中垃圾收集运行1分钟,则吞吐量为99%。
高吞吐量的好处:高效率的利用CPU时间,尽快完成程序的运算任务,主要适合于大量在后台运算不需要与用户进行太多前台交互的任务。
无法与CMS收集器(老年代)配合—所谓配合即某个收集器专门用于新生代,某个专门用于老年代。

4、Parallel Old 收集器(老年代)

5、CMS收集器

6、G1收集器


五、对象的内存分配规则(哪些对象进入新生代哪些进入老年代)


六、何时回收

一个对象实例化时 先去看伊甸园有没有足够的空间
如果有 不进行垃圾回收 ,对象直接在伊甸园存储.
如果伊甸园内存已满,会进行一次minor gc
然后再进行判断伊甸园中的内存是否足够
如果不足 则去看存活区的内存是否足够.
如果内存足够,把伊甸园部分活跃对象保存在存活区,然后把对象保存在伊甸园.
如果内存不足,向老年代发送请求,查询老年代的内存是否足够
如果老年代内存足够,将部分存活区的活跃对象存入老年代.然后把伊甸园的活跃对象放入存活区,对象依旧保存在伊甸园.
如果老年代内存不足,会进行一次full gc,之后老年代会再进行判断 内存是否足够,如果足够 同上.如果不足 会抛OutOfMemoryError.

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值