jvm学习笔记(二)

本文详细介绍了JVM的垃圾收集算法,包括标记-清除、复制、标记-整理和分代收集算法,以及各种算法的优缺点。同时,讨论了新生代和老年代的内存分配策略,并详细阐述了不同类型的垃圾收集器,如Serial、ParNew、Parallel Scavenge、serial Old、Parallel Old和CMS收集器的工作原理和特点。重点关注了CMS收集器的并发收集和内存碎片问题。
摘要由CSDN通过智能技术生成

接上篇


JVM的垃圾收集算法


1.标记-清除算法

这是最基础的收集算法,(Mark-Sweep),就如同名字所表达的一样,扫描整个内存区域,对可回收的对象进行标记,当扫描完时,再清除所有被标记的对象。

此算法的缺点有以下两点

效率不高。

会产生内存碎片,所谓内存碎片就是不连续的内存区域,这样可能会导致虽然有足够的内存但是却没有足够大的连续内存去分配给一个比较大的对象,从而导致一次FULL-GC


2.复制算法

复制算法的思想主要是将内存区域分成两部分,在分配内存的时候只使用其中的一部分内存,即任何时刻都保证有一部分是没有使用过的,每次收集的时候都将存活的对象复制到另一块区域,然后收集结束后直接清空当前扫描的区域。


3.标记-整理算法

 这种算法就是对标记-清除算法的改进,即清理完可回收的对象后,将仍然存活的对象向一端移动,这样就不会造成内存碎片。


4.分代收集算法

分代收集算法是根据对象的存活周期的不同将内存划分为几块,对这些不同的区域采用不同的算法。

大部分实现的虚拟机是讲java堆分为新生代和老年代,一般来说对新生代采用的是复制算法,对老年代一般采用标记-清除或者标记-整理算法


java堆的分代思想

新生代:顾名思义,就是用来存放新生对象的,在java的世界中,很多对象都是“朝生夕死”,所以专门划分出一块区域称作新生代来存放新生的对象,对于新生代一般来说会采用复制算法进行收集。IBM的专门研究表明,新生代中98%的对象是朝生夕死的,所以不需要划分两块相同大小的内存区域,通常新生代划分为三块,一块大的eden区,两块大小相等survivor区,如下图


hotpot虚拟机默认eden区和survivor区的大小比例为8:1,也就是说新生代最多可以使用到90%的空间,每次新生代发生gc时,虚拟机会把存活的对象全部拷贝到两块survivor区中空闲的一块,然后再清理其他区域。

老年代:顾名思义就是存放长久存活对象的区域,一般来说对象经过多次minor GC 仍然存活,就会被移动到老年代中,默认貌似是6次,可通过MaxTenuringThreshold来设置


垃圾收集器:

垃圾收集器就是对垃圾收集算法的实现,按照分代收集的思想,垃圾收集器可以分为新生代收集器和老生带收集器,按照回收线程数来分,又可分为单线程收集器和多线程收集器。

1.Serial收集器:是最基本,历史最悠久的收集器,它是一个单线程收集器,且工作时必须停止所有用户线程,这是用于新生代的收集器,所以采用了复制算法,它是client模式下默认的新生代收集器。

2.ParNew收集器:其实就是Serial收集器的多线程版,是Server模式下默认的新生代收集器,只有它和serial收集器可以配合CMS收集器一起工作。

3.Parallel Scavenge收集器:也是新生代收集器,多线程回收,看起来似乎和ParNew收集器没有什么区别,它的特点就是关注点和其他收集器不同,ParNew收集器注重将每次GC的时间尽量缩短,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量,所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,吞吐量= 运行用户代码总时间 / (运行用户代码总时间 + 垃圾收集时间),吞吐量高可以最高效率的利用CPU时间,尽快完成程序的运算任务,主要适用在后台运算而不需要与用户进行太多交互的任务,可以通过-XX:MaxGCPauseMillis和-XX:GCTimeRatio来设置吞吐量。

4.serial Old收集器:是serial收集的老年代版本,同样是单线程收集器,使用的是标记-整理算法。

5.Parallel Old收集器:是Parallel Scavenge收集器的老年代版本,多线程收集器,使用标记-整理算法,和Parallel Scavenge配合可以做到吞吐量最大优化。

6.cms收集器:基于标记-清除算法的收集器,是一款真正实现并发收集的收集器,即在GC的时候不会停止用户线程,整个过程分为4步:1、初始标记 2、并发标记 3、重新标记 4、并发清除,其中初始标记和重新标记仍然需要停止用户线程,但停顿时间都不会很长,它是一款优秀的收集器,并发收集低停顿,但也有一些缺点:1、CMS收集器对CPU资源比较敏感,因为是并发的,它虽然不会导致用户线程停顿,但会因为占用CPU资源而导致应用程序变慢,总吞吐量下降。2、无法处理浮动垃圾,浮动垃圾就是在并发清除时由于用户线程运行而产生的垃圾,CMS收集器无法在本次收集中清理他们,也是由于在收集阶段用户线程需要运行,所以需要预留一部分空间给用户线程使用。3、由于采用的是标记-清理算法,会产生内存碎片。


垃圾收集器参数总结:(原谅我不愿打这么多字··)


内存分配与回收策略


1.对象优先在Eden区分配

2.大对象直接进入老年代

3.长期存活的对象将进入老年代



这三条策略都没什么说的,··挺好理解的吧


4.动态对象年龄判定

为了适应不同程序的内存情况,虚拟机不会总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升到老年代,如果Survivor空间中相同年龄所有对象大小的总和大于Survivor的空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代


5.空间分配担保


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值