JAVA中的垃圾回收器(1)

一)垃圾回收器概述:

1.1)按照线程数来区分:

串行回收指的是在同一时间端内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾回收工作结束,在诸如单CPU处理器或者较小的应用内存等硬件平台不是特别优越的场合,出行回收器的性能表现可以超过并行回收期和并发回收器,所以串行回收默认被应用在客户端的client模式下面的JVM中,但是在并发能力比较强的CPU上,并行回收器产生的停顿时间要大于串行回收器,和串行回收相反,并行收集可以运用多个CPU同时进行垃圾回收,因此提升了应用的吞吐量,不过并行回收仍然和串行回收一样,采用独占式,会造成STW;

1.2)按照工作模式来分,可以分为并发式垃圾回收器和独占式垃圾回收器:

并发式垃圾回收器可以和用户线程交替进行工作,尽可能的来减少应用线程的停顿时间

独占式垃圾回收器一旦运行,就停止应用程序中的所有用户线程,直到垃圾回收器GC完成

 

吞吐量:运行用户代码的时间占总运行时间的比例,总运行时间=程序的运行时间(a)+GC垃圾回收的总时间(b)

暂停时间=STW时间

收集频率:回收的频率低,不代表一次GC的时间短,大学洗衣服

一次攒一快洗(时间比较长)VS经常洗(一天一洗,时间比较短),频率越高,STW时间短一点

 

1)吞吐量:吞吐量越大越好,就是用户线程所执行的时间在整个JVM生命周期中所占用的时间越长,那么垃圾频率就越低,但是每一次执行GC,那么用户线程停止,STW时间就越长(类比于洗衣服),一次性的暂停时间就很长,用户体验感就可能很差劲,但是高吞吐量单位时间内用户线程做的事情更多

2)低延迟:注重每一次的暂停时间变短,用户线程暂停时间短,那么垃圾回收GC的频率就越高,因为暂停时间短,每一次GC都收集不了多少垃圾,但是线程频繁切换也需要时间,每一次本来就注重低延迟,要求GC垃圾回收短,况且线程上下文切换还消耗时间,每一次GC垃圾又回收不了多少,那么最终一共的STW时间肯定会比吞吐量的STW时间长(类比于洗衣服)高吞吐量和低延迟是矛盾的

这就类似于洗衣服,从宿舍去水房的时间和从水房回到宿舍的时间就类似于线程切换

1)高吞吐量比较好是因为这会让应用程序的最终用户感觉只有应用线程在做生产性工作,直觉上,吞吐量越高程序运行越快

2)低暂停时间比较好是因为从嘴中用户的角度来看不管是GC还是其他原因来说导致一个应用被挂起始终是不好的,这取决于应用程序的类型,有的时候甚至于说短暂的200毫秒暂停都有可能直接打断终端用户的体验,因此具有低的较大的暂停时间是日常重要的,特别是一个交互性的应用程序

3)不幸的是高吞吐量和低暂停时间是一对相互竞争的目标或者说是矛盾,如果以高吞吐量优先,那么必然需要降低垃圾GC收集的时间频率,每一次垃圾收集的时间长一些,这也会导致GC需要更长时间的来执行GC

4)相反,如果以低延迟为主要目标,那么为了降低每一次内存回收时候的暂停时间,只能频繁的进行内存回收,但是这又引起了年轻代的内存的缩减和导致最终吞吐量的下降

在设计或者使用GC算法的时候,必须要确定目标,一个GC算法只可能针对于两个目标之一,就是只是关注于较大吞吐量和最小暂停时间或者找到一个二者的初衷,现在的标准是在最大吞吐量的有限的情况下,降低停顿时间

和用户交互的程序,延迟要短一些,争取在垃圾回收的过程中多线程回收

有的是服务器端,吞吐量要高一些

G1垃圾回收器就是可以保证在给定停顿时间的基础上,尽量的提高吞吐量

JDK7之前,实线,Serial OLD GC是CMS的后备方案

在JDK9中取消了红线组合

在JDK14中绿线会被删除

CMS和PSGC框架不同,不可以一起使用,PNGC和PSGC性能差不多

CMS:不能是在老年代空间满的时候进行使用,需要提前进行回收,因为CMS是并发的,在回收的时候用户线程还在执行,用户线程还有可能制造新的垃圾,所以需要提前进行回收,那如果说回收的比较晚,垃圾制造的速度比回收的速度还要快,可能CMS回收失败一旦失败,所以要使用SOGC作为备用方案,赶紧把用户线程停下来进行全部GC,应该达到一定阈值以后回收,单核CPU是单线程垃圾收集器比多线程垃圾收集器要高,因为防止进行大量的线程切换;

Serial和Serial old单线程垃圾回收器

ParNew针对于单线程的升级版本是多线程的垃圾回收器:

Parallel Scavenge/Parallel Old:吞吐量优先的垃圾回收期,以回收内存为主,速度比较低,这个垃圾回收器只是保证了吞吐量,但是实际程序是让用户有最少的等待时间

CMS:垃圾回收器可以保证最小的等待时间,就是快,不影响用户久等,不需要将垃圾全部清除掉,多进行几次GC不就行了嘛,需要手动指定

为什么CMS和Parallel Scavenge不能一起用,设计理念不同

G1:可控垃圾回收时间的垃圾回收器(JDK 9以后HotSpot默认的垃圾的回收器)

分成多个区,为什么分区算法是可控的?因为分区算法里面有很多区,再进行垃圾回收的时候,假设一共有4个区,他不会保证在这一次GC将A B C D四个区域的垃圾全部回收,而是保证的是可控时间,但是会保证时间到了就罢工,如果时间允许的话,G1垃圾回收器会多回收几个区域,如果时间不允许,我少干一点活,到点就下班;

分代算法为什么时间不可控?

ZGC:停顿时间极短,不超过10ms情况下尽量提高垃圾回收吞吐量的垃圾回收器

二)Serial(新生代单线程垃圾回收器)+Serial Old(老年代单线程垃圾回收器)

新生代使用serial的时候老年代默认使用Serial Old,在执行的时候必须停止所有的用户线程

Serial是最基本,历史最久远的垃圾回收器了,JDK1.3以前是回收新生代唯一的选择

Serial垃圾回收器是作为HotSpot虚拟机Client模式下默认的新生代垃圾回收器

Serial垃圾收集器采用复制算法,串行回收和STW机制的方式执行垃圾回收

除了年轻代以外,Serial垃圾收集器还提供了用于老年代垃圾收集的Serial Old垃圾回收器,Serial Old垃圾收集器同样也是采用了串行回收和STW机制,老年代使用的是标记整理算法

Serial Old是用于运行在客户端模式下面的默认的老年代的垃圾收集器

Serial Old在Server模式下面的主要有两个用途:

1)和新生代的Parallel Scavenge配合使用

2)作为CMS老年代收集器的后备垃圾收集方案

这俩收集器完全就是一个单线程的垃圾收集器,但是他的单线程的意义并不仅仅只是他只会使用一个CPU和一条收集线程来去完成垃圾收集工作,更重要的是在它进行垃圾收集的时候必须停止其他的工作线程,直到它垃圾收集结束

-XX:PrintCommandLineFlags

-XX:+UseSerialGC

表明新生代使用Serial GC,老年代使用Serial Old GC

然后可以通过jps验证一下,jinfo -flag UseSerialGC +进程的ID

总结:只是适合于单核CPU,对于交互性比较强的应用而言,这种垃圾收集器是不能接受的,一般在JAVA WEB应用程序中是不会使用这种串行垃圾收集器的

优点:简单而高效,和其他收集器的单线程相比,对于限定单个CPU的环境来说Serial收集器由于没有线程交互的开销,专心于做垃圾收集自然可以活得最高的单线程执行收集效率,运行在客户端模式下的虚拟机是一个不错的选择,在用户的桌面应用场景中,可用于内存不大,可以在较短时间内完成垃圾收集,只要不是频繁的发生,使用穿行回收器是可以接受的

在HotSpot虚拟机中,使用-XX:+UseSerialGC参数可以指定新生代和老年代都是用串行垃圾收集器等价于新生代使用Serial GC老年代使用Serial Old GC

缺点:串行垃圾回收器会导致STW

三)parNew新生代收集器

1)ParNew新生代并行垃圾回收器+和Serial Old单线程串行垃圾回收器或者是CMS(老年代并行垃圾回收器一起使用

2)如果说Serial GC是年轻代中的单线程垃圾收集器,那么ParNew收集器就是Serial收集器的多线程版本,Par是Parallel的缩写,New是回收新生代

3)ParNew垃圾回收器是新生代的多线程垃圾回收器和Serial 没啥区别,在年轻代也是使用复制算法,STW,它是很多JVM在Server模式下面的新生代的默认的垃圾回收器

1)对于新生代来说,回收次数频繁,使用并行方式比较高效,对于老年代,回收次数少,使用串行的方式高效,因为CPU并行需要切换资源,穿行可以省去切换线程资源

2)ParNew在服务器端模式下是多核CPU的场景,这个时候就不和客户端一样是一个单线程的垃圾回收器了,服务器端硬件更多一些,在老年代可以使用CMS或者是Serial Old,在JDK9中Serial Old不能再和ParewNew使用了,在JDK14CMS也被移除了,这个时候ParNew就比较尴尬了,对于新生代,使用多线程垃圾回收器,使得GC的时间更短,垃圾回收更高效STW时间更短,但是在老年代,标记整理算法效率比较差,涉及到内存碎片整理,所以说就是用单线程的了,单CPU:同一时刻只能由一个线程执行

3)设置线程数量不要超过CPU核数,防止多个线程抢夺CPU,和CPU核数相同越好

-XX:PrintCommandLineFlags -XX:+UseParNewSerialGC -XX:+UseConcMarkSweepGC

1)ParNew收集器运行在多CPU模式下,可以充分的利用多CPU,多核心等物理硬件资源优势,可以更快速的完成垃圾收集,来提升程序的吞吐量

2)但是在单个CPU的换进修改,ParNew收集器不必Serial收集器更高效,虽然Serial收集器是基于穿行回收,但是由于CPU不需要频繁的进行切换任务,因此可以有效地避免多线程交互过程中产生的一些额外开销,当前除了Serial以外,目前只有ParNew可以和CMS垃圾收集器配合工作

3)在程序中,开发人员可以通过选项-XX:+UseParNewGc来指定使用ParNew收集器来执行内存回收任务,他表示年轻代使用并行收集器并不影响老年代

4)使用-XX:ParallelGCThreads来限制线程数量,默认开启和CPU数据相同的线程数

四)Parallel Scavenge并行新生代垃圾回收器和Parallel Old老年代垃圾回收器:

1)吞吐量优先用户线程执行时间越长越好,JDK8默认GC,一开始来说Parallel Scavenge吞吐量的并行新生代垃圾收集器,一开始它是搭配Serial Old一起来做垃圾收集的,但是Parallel Scavenge本身在新生代是并行垃圾回收器,老年代用了一个串行的垃圾回收器,就不太好,所以最终Parallel Old老年代并行垃圾回收器出现了,Parallel Scavenge收集器在JDK1.6提供了用于执行老年代垃圾收集的Parallel Old垃圾收集器,用来代替来年代的Serial Old垃圾收集器,Parallel本身也是采用了标记压缩算法,STW;

2)Parallel Scavenge和ParNew垃圾回收器性能差不多,它们都是回收新生代的,但是底层使用的GC框架是不同的,是自成一派的,包括G1也是自成一派的;

3)HotSpot年轻代中除了拥有ParNew收集器是基于并行回收的以外,Parallel Scavenge收集器本身也采用了复制算法,并行回收和STW机制;

那么Parallel收集器的出现是否多此一举呢?

1)和ParNew收集器不同,Parallel Scavenge收集器的目标则是先打到一个可控制的吞吐量,他也是被称之为是吞吐量优先的垃圾回收器

2)自适应调节策略也是Parallel Scavenge的一个重要区别,就是在整个JVM运行的过程中,根据当前运行的情况来做一个性能监控,来调整内存的分配情况,来达到最优的策略;

1)凡是提高吞吐量的:一定是和后台运行的,不和用户交互性场景强的,高吞吐量可以高效的利用CPU时间,尽快完成程序的运算任务意味着一次STW暂停时间可能长一些主要适合那些在后台计算而不需要交互的任务(但是暂停时间优先就是适用于那些交互性比较强的任务)比如说那些执行批量处理,订单处理,工资支付,科学计算的程序,在这种模式下,年轻代的大小,Eden和Survivor的比例、晋升老年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点,自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别

2)自适应调节策略:会根据当前JVM的运行情况进行性能监控

动态地去调整内存分配情况意识和达到最优的策略,内存分配情况来到到低延迟或者是吞吐量优先的策略,和用户交互性强的:保证低延迟,暂停时间要短,保证在服务后台进行数据运算的,要保证高吞吐量;

为什么在JDK1.6的时候要使用Parallel Old收集器代替Serial Old收集器呢?

在Parallel Old出来之前肯定是只能使用Serial Old收集器

意义非常大,因为此时如果没有Parallel Old的时候新生代垃圾回收器使用Parallel,而老年代使用Serial Old,此时使用Serial Old会存在一定的问题,因为既然新生代使用了Parallel,那么后台肯定是不和用户做大量交互的服务器端(交互性比较弱的)进行使用,通常服务器端硬件的配置比较高,肯定是多核CPU,如果服务器配置比较低的话,单核CPU,那么新生代老年代直接都是用串行垃圾回收不就行了吗,在一个高性能的场景下硬件配置比较高,多核CPU,新生代使用并行垃圾回收器效率比较高,充分利用CPU多核资源,老年代使用串行垃圾回收器,此时的性能肯定得不到最大的提升更好地发挥,拖累服务器性能的效果了,达不到最大吞吐量的一个效果了,更好的对硬件性能做发挥;

在吞吐量优先的应用场景中,也就是服务器完成任务的数量越多越好,Parallel收集器和Parallel Old收集器的组合在服务器模式下的内存回收性能比较不错

参数设置:就是-XX:+UseParallelGC和-XX:+UseParallelOldGC当一个参数开启以后,另一个参数也会默认开启

最好CPU核数等于垃圾回收线程数,但是还是可以空闲出一些资源留给其他任务来执行

-XX:+PrintCommandLineFlags -XX:+ParallelGC

根据下面参数来了解自适应调节策略:

1)-XX:MaxGCPauseMillis:设置垃圾收集器最大停顿时间,就是STW的时间,默认是毫秒,此参数设置需要谨慎,为了尽可能地把停顿时间控制在MaxGCPauseMills以内,收集器在工作的时候会调整堆和其他的一些参数,对于用户来说,停顿时间越短,体验感越好,但是在服务器端,我们注重与整体的高并发,整体的吞吐量,所以服务器端适合于Parallel进行控制

2)-XX:GCTTimeRatio:垃圾收集时间占用的总时间的比例,用来衡量吞吐量的大小,默认是垃圾回收时间不超过1%,与前一个-XX:MaxGCPauseMillis参数具有一定的矛盾性,暂停时间越长,Radio参数就容易超过设定的比例

垃圾收集时间和吞吐量是互补的,吞吐量是对于服务器端来说执行任务越多越好

3)假设此时要是设置最大停顿时间是10ms,再进行垃圾回收的时候会尽可能的想办法把时间控制在10ms以内,要想实现垃圾回收的时间比较短,每一次垃圾回收比较短,那么就只能控制堆的大小,想让停顿时间短,那么垃圾回收的时间就比较短,垃圾回收器把堆控制的小一些,每一次GC时间就比较短,但是堆空间比较小,堆空间容易满,但是可能经常发生GC,GC频率增高,这样子吞吐量反而降低了,就会导致用户线程执行的总时长比较短,所以第一个参数使用需要谨慎;

4)自适应调节策略:尽量开发中的满足吞吐量和停顿时间,具有自动调节功能

5)-XX:+UseAdaptiveSizePolicy设置Parallel Scavenge的比例,京生老年代的对象的年龄等参数会被自动调整,已达堆大小,吞吐量和停顿时间之间的平衡点,再手动调优比较困难的场合,可以直接使用这种自适应的方式,进指定虚拟机的最大堆,目标的吞吐量和停顿时间,让虚拟机自己完成调优工作;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/122084.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka KRaft模式探索

1.概述 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer,以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器的选举等。 2.内容…

python爬虫request和BeautifulSoup使用

request使用 1.安装request pip install request2.引入库 import requests3.编写代码 发送请求 我们通过以下代码可以打开豆瓣top250的网站 response requests.get(f"https://movie.douban.com/top250")但因为该网站加入了反爬机制,所以…

非遗主题网站的设计与实现基于PHP实现

包括源码参考论文 下载地址: https://juzhendongli.store/commodity/details/18

Linux Centos7安装后,无法查询到IP地址,无ens0,只有lo和ens33的解决方案

文章目录 前言1 查看network-scripts目录2 创建并配置 ifcfg-ens33 文件3 禁用NetworkManager4 重新启动网络服务总结 前言 在VMware中,安装Linux centos7操作系统后,想查询本机的IP地址,执行ifconfig命令 ifconfig结果如下: 结…

【Linux】权限完结

个人主页点击直达:小白不是程序媛 系列专栏:Linux被操作记 目录 前言 chown指令 chgrp指令 文件类型 file指令 目录的权限 粘滞位 umask指令 权限总结 前言 上篇文章我们说到对于一个文件所属者和所属组都是同一个人时,使用所属者身…

【NLP】word复制指定内容到新的word文档

目录 1.python代码 2.结果 需求: 复制word文档里的两个关键字(例如“起始位置”到“结束位置”)之间的内容到新的word文档。 前提:安装win32包,通过pip install pywin32命令直接安装。话不多说,直接上代码…

RSA:基于小加密指数的攻击方式与思维技巧

目录 目录 目录 零、前言 一、小加密指数爆破 [FSCTF]RSA签到 思路: 二、基于小加密指数的有限域开根 [NCTF 2019]easyRSA 思路: 三、基于小加密指数的CRT [0CTF 2016] rsa 思路: 零、前言 最近,发现自己做题思路比较…

设计模式之桥梁模式

什么是桥梁模式 桥梁模式(Bridge Pattern)也称为桥接模式,属于结构型模式,它主要目的是通过组合的方式建立两个类之间的联系,而不是继承。桥梁模式将抽象部分与它的具体实现部分分离,使它们都可以独立地变…

GnuTLS recv error (-110): The TLS connection was non-properly terminated

ubuntu git下载提示 GnuTLS recv error (-110): The TLS connection was non-properly terminated解决方法 git config --global --unset http.https://github.com.proxy

Day13力扣打卡

打卡记录 奖励最顶尖的 k 名学生(哈希表排序) 用哈希表对所有的positive与negative词条进行映射,然后遍历求解。tip:常用的分割字符串的操作:1.stringstream配合getline() [格式buf, string, char]2.string.find()[find未找到目标会返回npos…

别处拿来的VUE项目 npm run serve报错

问题现象: 从别处拷贝来的VUE项目,根据说明通过npm install 加载了项目依赖 ,但是运行npm run serve里报错: npm ERR! Missing script: "serve" npm ERR! npm ERR! To see a list of scripts, run: npm ERR! npm ru…

Java 将数据导出到Excel并发送到在线文档

一、需求 现将列表数据&#xff0c;导出到excel,并将文件发送到在线文档&#xff0c;摒弃了以往的直接在前端下载的老旧模式。 二、pom依赖 <!-- redission --><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-…

ActiveMQ消息中间件简介

一、ActiveMQ简介 ActiveMQ是Apache出品&#xff0c;最流行的&#xff0c;能力强劲的开源消息总线。ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMS Provide实现。尽管JMS规范出台已经是很久的事情了&#xff0c;但是JMS在当今的J2EE应用中仍然扮演这特殊的地位。 二、Active…

云计算模式的区域LIS系统源码,基于ASP.NET+JQuery、EasyUI+MVC技术架构开发

云计算模式的区域LIS系统源码 云LIS系统源码&#xff0c;自主版权 LIS系统是专为医院检验科的仪器设备能与计算机连接。可通过LIS系统向仪器发送指令&#xff0c;让仪器自动操作和接收仪器数据。并快速的将检验仪器中的数据导入到医生工作站中进行管理&#xff0c;且可将检验结…

springboot项目打jar包,运行时提示jar中没有主清单属性

可能性一&#xff1a; 没有在pom中加入maven插件 在pom中加入下方代码即可。 <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</ve…

039-第三代软件开发-PDF阅读器

第三代软件开发-PDF阅读器 文章目录 第三代软件开发-PDF阅读器项目介绍PDF阅读器1 初始化PDF view2 qml 中使用3 创建模块 关键字&#xff1a; Qt、 Qml、 pdf、 LTDev、 本地 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Met…

如何快速排查SSD IO延迟抖动问题?

一块固态硬盘设计背后&#xff0c;有硬件控制器&#xff0c;NAND闪存颗粒、DRAM&#xff0c;还有固件FTL算法等。SSD设计的本身其实是一件特别复杂的过程&#xff0c;需要考虑各种客户需求且要保证可靠性、性能、稳定性。 针对SSD的相关性能测试&#xff0c;SNIA也有专门针对SS…

【RabbitMQ 实战】12 镜像队列

一、镜像队列的概念 RabbitMQ的镜像队列是将消息副本存储在一组节点上&#xff0c;以提高可用性和可靠性。镜像队列将队列中的消息复制到一个或多个其他节点上&#xff0c;并使这些节点上的队列保持同步。当一个节点失败时&#xff0c;其他节点上的队列不受影响&#xff0c;因…

漏洞复现-showdoc文件上传_v2.8.3_(CNVD-2020-26585)

showdoc文件上传_v2.8.3_CNVD-2020-26585 漏洞信息 showdoc 2.8.3 以下版本中存在安全漏洞CNVD-2020-26585文件上传漏洞 描述 ShowDoc是一个非常适合IT团队的在线API文档、技术文档工具。通过showdoc&#xff0c;你可以方便地使用markdown语法来书写出美观的API文档、数据字…

java后端返回给前端不为空的属性

问题背景&#xff1a; 目前遇到的一个问题。一个对象里面定义了数组、集合、和字符串属性等&#xff0c;但是返回给前端的时候数组和集合都是空的&#xff0c;前端接收到的是“” 一个空字符。然后保存的时候又把空字符传给后端&#xff0c;出现了数据结构不匹配导致报错。 解…