首页 > 编程知识 正文

jvm有哪些垃圾回收算法,Jvm垃圾回收算法

时间:2023-05-06 14:14:39 阅读:189653 作者:4093

jvm的三种算法和10种垃圾收集器jvm怎么知道堆里面的对象是无用数据,有两种方式:

1.引用计数法:

每个对象都有引用计数属性,添加引用时计数增加1,释放引用时计数减少1,当计数变为0时可以回收。 这个方法很简单,不能解决对象相互之间的循环引用问题。

2.跟查找GC Roots

(Reachability Analysis ) :从GC Roots开始向下检索,将检索通过的路径称为参照链。 如果对象未通过引用链连接到GC Roots,则该对象将被证明为不可用,即无法访问。

jvm的三种基本算法

1.1标记擦除算法(完成的乐曲sweep ) ) ) )。

一张存储器中要回收的数据、标记、直接清除

1.2复印算法(Copying ) ) ) ) ) )。

将一个内存中的数据直接复制到另一个内存,并清除以前的内存区域

1.3标记整理算法(完成的乐曲compact ) )。

将存储器内的数据、标签集中移动到存储器的一侧,进行清理

1.4按代收集算法

注:该算法是在物理逻辑上将内存堆栈分为年轻一代、老一代,根据在删除不同世代的目标时使用什么样的算法而提出的算法

10种垃圾回收器

算法是GC的垃圾回收策略,垃圾收集器是基于算法进行垃圾处理的具体实现

2.1 Serial收集器

串行(串行)垃圾收集器是最基本、发展历史最悠久的收集器

JDK1.3.1前是HotSpotqsddn世代收集的唯一选择;

串行收集器是JAVA虚拟机在客户端模式下运行的缺省qsddn世代收集器,最多可达JDK1.7。 也有比其他收集器更好的地方。 简单高效。 对于限制单个CPU的环境(与其他收集器的单线程相比),Serial收集器没有线程交互开销,因此专心进行垃圾回收当然可以获得最高的单线程收集效率。 在用户桌面应用程序的情况下,分配给虚拟机管理的内存通常不大。 聚集了几十兆到一两百兆的qsddn世代,只有qsddn世代使用的内存,桌面应用基本上不会变得更大。 休眠时间可以完全控制在几十毫秒到一百毫秒以内,只要不频繁发生,这种休眠是可以接受的。 因此,序列收集器适合运行。

STW : stoptheword停止所有工作线程; 采用复制算法;

注:收集器随着内存的增加,执行效率太慢。 例如,hlt最初住的是5平方米的房子,打扫房子很快,S&; 住在P500N的平房里时,打扫房子花了太多时间,这个单线程不能用了,后面有一个多线程版本的par new收集器

2.2 Serial Old收集器

与Serial相比,Serial Old应用于旧时代的垃圾回收器,也是单线程的。 但是算法不是copy,而是完成的歌曲compact标签整理算法,由stw:暂停所有线程进行垃圾回收

因此,如果将Serial和Serial Old组合使用,则在可用内存一般不大(几十到一两百)的服务器环境中,不适合当前的大容量内存

2.3ParNew收集器

ParNew垃圾收集器是Serial收集器的改进多线程版本,除多线程外(由于内存增加)的其他操作和特点与Serial收集器相同,实现算法与Serial完全相同,并在stw上运行

但是,CPU数量为1个或! 少于个时,此收集器的性能不如序列好。 用户线程会变慢,因为它占用用户线程的CPU时间片(上下文切换除外)

在Server模式下,ParNew收集器是非常重要的收集器。 这是因为除了Serial之外,目前只有这个可以与CMS收集器配合使用。 CMS是HotSpot在JDK1.5上推出的第一个真正意义上的同时(Concurrent )收集器,首次实现了垃圾回收线程和用户线程(基本上)同时运行。

1 ) CMS作为老一代收集器,但无法与JDK1.4中已存在的qsddn代收集器并行扫描协同工作;

)因为并行扫描(和G1 )都不使用传统的GC收集器代码框架,而是单独实现的; 剩下的几个收集器共享了一部分帧代码。

参数的设定

xx : use conc实现的歌曲SweepGC :如果指定使用CMS,则缺省情况下将使用ParNew作为qsddn代收集器。

“xx : useparnewgc”:“强制指定使用parnew;

xx : parallelgcthreads :指定垃圾回收线程的数量,以及ParNew在缺省情况下打开的收集线程和CPU的数量

2.4.Parallel Old

这是Serial Old的多线程版本,适用于旧时代的收集器,既是标记组织算法,也是stw的运行收集。 但是,如果CPU数量少,性能就不一样了。 但是,现在无论是PC还是服务器CPU的数量都不是性能

瓶颈限制了,所以目前它跟Parallel Scavenge的配合是吞吐量优先场景的优先收集器选择。

2.5Parallel Scavenge
一种qsddn代垃圾收集器,与 ParNew相比不可以与cms一起组合使用,PS也是复制算法,它与前两种收集器最大的区别是,它关注的是吞吐量而不是延迟。也被称为是吞吐量优先的收集器。其中,吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。
主要使用场景:主要适合在后台运算而不是太多交互的任务,高吞吐量则可以最高效率的利用CPU时间,尽快的完成程序的运算任务。当然,如果想要降低停顿时间,相应的也会影响吞吐量
2.6 CMS
CMS,Concurrent 成就的歌曲 Sweep,这是一款真正的并发收集器,就是在线程执行过程中也可以进行垃圾收集的收集器,在一些对响应时间有很高要求的应用或网站中,用户程序不能有长时间的停顿,CMS 可以用于此场景。 分为四个过程 ,1初始标记 ,2并发标记,3重新标记,4并发清理
CMS执行流程图

CMS采用了多种方式尽可能降低GC的暂停时间,减少用户程序停顿。
停顿时间降低的同时牺牲了CPU吞吐量 。因为并发情况占用大量cpu资源
这是在停顿时间和性能间做出的取舍,可以简单理解为"空间(性能)"换时间
CMS 是一个承前启后的收集器
下面是不分代收集器
2.7 G1(Garbage First)
在JDK7就已加入JVM的收集器大家庭中,成为HotSpot重点发展的垃圾回收技术。同优秀的CMS垃圾回收器一样,G1也是关注最小时延的垃圾回收器,也同样适合大尺寸堆内存的垃圾收集,官方也推荐使用G1来代替选择CMS。G1最大的特点是引入分区的思路,弱化了分代的概念,合理利用垃圾收集各个周期的资源,解决了其他收集器甚至CMS的众多缺陷
G1收集器,是比前面的更优秀,真正有突破的一款垃圾收集器。其实在G1中还是保留了分代的概念,但是实际上已经在qsddn代和老年代中没有物理隔离了。在G1中,内存空间被分割成一个个的Region区,所谓qsddn代和老年代,都是由一个个region组成的。同时G1也不需要跟别的收集器一起配合使用,自己就可以搞定所有内存区域。整体上来讲不是一个分代收集器,是一个通吃收集器。这也是JVM内存管理和垃圾收集的一个发展趋势。从后面zgc中我们可以更清晰的看到这个变化。

G1采用了标记-整理算法,避免了CMS中的内存碎片问题,另外它能达到可控的垃圾时间。是一款优秀的收集器。即便如此,从2004年第一篇论文发表到真正商用推出,也是到了jdk1.7。实现上并不是那么容易的。

G1的工作过程:

初始标记:这个过程跟CMS第一个过程差不多,只是标记一下GC Root关联的对象。

并发标记:这个过程时间比较久,分析GC Root到所有对象的可达性分析。如果从GC Root节点开始遍历所有对象会比较耗时,实际上JVM也不是这么做的。JVM是使用Remembered Set保存了对象引用的调用信息,在可达性分析的时候只需要同时遍历remembered set就好了,不需要从根节点开始挨个遍历。

最终标记:由于并发标记阶段,用户线程仍然在工作,会对标记产生一些偏差,这时候需要通过remembered set log来记录这些改变,在这个阶段将改变合并到remembered set中。完成最终标记。

筛选清除:通过标记整理的算法,根据用户配置的回收时间,和维护的优先级列表,优先收集价值最大的region。收集阶段是基于标记-整理和复制算法实现
2.8 ZGC
zgc是jdk11中要发布的最新垃圾收集器。完全没有分代的概念,先说下它的优点吧,官方给出的是无碎片,时间可控,超大堆。
学习连接 https://www.jianshu.com/p/6f89fd5842bf
2.9 Shenandoah
Shenandoah是一款concurrent及parallel的垃圾收集器;跟ZGC一样也是面向low-pause-time的垃圾收集器,不过ZGC是基于colored pointers来实现,而Shenandoah GC是基于brooks pointers来实现。
其实低停顿的GC,业界早就出现,只不过Java比较晚
Azul的Zing中C4 GC ldmj选择
oracle中的HotSpot ZGC JDK11的选择
R大说ZGC说抄袭Azul的,两者是等价的。
可以参考 这篇文章学习连接
2.10 Epsilon

java 11 新的Epsilon垃圾收集器
Epsilon(A No-Op Garbage Collector)垃圾回收器控制内存分配,但是不执行任何垃圾回收工作。一旦java的堆被耗尽,jvm就直接关闭。设计的目的是提供一个完全消极的GC实现,分配有限的内存分配,最大限度降低消费内存占用量和内存吞吐时的延迟时间。一个好的实现是隔离代码变化,不影响其他GC,最小限度的改变其他的JVM代码。
参考一下
链接:Epsilon学习连接

最后附一张各个收集器的组合流程图

最后找到一个非常不错的博客,写了许多关于jvm的知识,大家可以去学习一下
添加链接描述

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。