当前位置: 首页 > news >正文

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

相关文章:

JAVA中的垃圾回收器(1)

一)垃圾回收器概述: 1.1)按照线程数来区分: 串行回收指的是在同一时间端内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾回收工作结束,在诸如单CPU处理器或者较小的应用内存等硬件平台不是特别优越的场合,出行…...

Windows 10/11如何恢复永久删除的文件?

数据丢失在我们的工作生活中经常发生。当你决定清理硬盘或U盘时,你会删除一些文件夹或文件。如果你通过右键单击删除文件,则可以很容易从回收站恢复已删除的文件。但是,如果你按Shift Delete键、清空回收站或删除大于8998MB的大文件夹&#…...

【Shell 系列教程】shell介绍(一)

文章目录 前言Shell 脚本Shell 环境第一个shell脚本运行 Shell 脚本有两种方法:1、作为可执行程序2、作为解释器参数 前言 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。 Sh…...

考研数学中放缩法和无穷项求和

考研数学放缩法和无穷项求和 放缩法专题例子1例子2例子3例子4例子5 放缩法专题 本文以例子为切入,对一些常用的放缩方法进行总结归纳,以期让读者对相关问题有一定的应对手段。 例子1 问题:2020年高数甲,选择题第1题。 lim ⁡ …...

计算机网络常识

文章目录 1、HTTP2、HTTP状态码1xx(信息性状态码):2xx(成功状态码):3xx(重定向状态码):4xx(客户端错误状态码):5xx(服务器…...

React之Jsx如何转换成真实DOM

一、是什么 react通过将组件编写的JSX映射到屏幕&#xff0c;以及组件中的状态发生了变化之后 React会将这些「变化」更新到屏幕上 在前面文章了解中&#xff0c;JSX通过babel最终转化成React.createElement这种形式&#xff0c;例如&#xff1a; <div>< img src&q…...

OpenCV学习(六)——图像算术运算(加法、融合与按位运算)

图像算术运算 6. 图像算术运算6.1 图像加法6.2 图像融合6.3 按位运算 6. 图像算术运算 6.1 图像加法 OpenCV加法是饱和运算Numpy加法是模运算 import cv2 import numpy as npx np.uint8([250]) y np.uint8([10])# OpenCV加法 print(cv2.add(x, y)) # 25010 260 > 255…...

如何做好一次代码审查,什么样是一次优秀的代码审查,静态代码分析工具有哪些

代码审查是确保代码质量、提升团队协作效率、分享知识和技能的重要过程。以下是进行优秀代码审查的一些指南&#xff1a; 如何做好代码审查&#xff1a; 理解代码的背景和目的&#xff1a; 在开始审查前&#xff0c;确保你了解这次提交的背景和目的&#xff0c;这有助于更准确…...

【Android】一个contentResolver引起的内存泄漏问题分析

长时间的压力测试后&#xff0c;系统发生了重启&#xff0c;报错log如下 JNI ERROR (app bug): global reference table overflow (max51200) global reference table overflow的log 08-08 04:11:53.052912 973 3243 F zygote64: indirect_reference_table.cc:256] JNI ER…...

2023年正版win10/win11系统安装教学(纯净版)

第一步&#xff1a;准备一个8G容量以上的U盘。 注意&#xff0c;在制作系统盘时会格式化U盘&#xff0c;所以最好准备个空U盘&#xff0c;防止资料丢失。 第二步&#xff1a;制作系统盘。 安装win10 进入windows官网 官网win10下载地址&#xff1a;https://www.microsoft.c…...

系统架构设计师-第11章-未来信息综合技术-软考学习笔记

未来信息综合技术是指近年来新技术发展而提出的一些新概念、新知识、新产品 信息物理系统(CPS ) &#xff0c;人工智能( A l) &#xff0c;机器人、边缘计算、数字孪生、云计算和大数据等技术 信息物理系统技术概述 信息物理系统的概念 信息物理系统是控制系统、嵌入式系统…...

Python __new__()方法详解

__new__() 是一种负责创建类实例的静态方法&#xff0c;它无需使用 staticmethod 装饰器修饰&#xff0c;且该方法会优先 __init__() 初始化方法被调用。 一般情况下&#xff0c;覆写 __new__() 的实现将会使用合适的参数调用其超类的 super().__new__()&#xff0c;并在返回之…...

虹科 | 解决方案 | 汽车示波器 索赔管理方案

索赔管理 Pico汽车示波器应用于主机厂/供应商与服务店/4S店的协作&#xff0c;实现产品索赔工作的高效管理&#xff1b;同时收集的故障波形数据&#xff0c;便于日后的产品优化和改进 故障记录 在索赔申请过程中&#xff0c;Pico汽车示波器的数据记录功能可以用于捕捉故障时的…...

详解Jmeter中的BeanShell脚本

BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法&#xff0c;所以它和java是可以无缝衔接的&#xff0c;学了Java的一些基本语法后&#xff0c;就可以来在Jmeter中写写BeanShell脚本了 在利用jmeter进行接口测试或者性能测试的时候&#xff0c…...

前端和后端 优化

1.前端资源优化 1.1 html结构优化 保证简洁、清晰的html结构&#xff0c;减少或避免多余的html标签 使用HTML5的web语义化标签&#xff0c;结构清晰且利于seo css文件在head中引入&#xff0c;js文件放在body底部引入&#xff0c;这样做可以防止阻塞。另外如果有需要提前加载的…...

C++编译与运行:其二、编译期和运行期的区别

C的编译分为四步&#xff0c;最终生成一个可执行文件。 C的运行&#xff0c;就是将可执行文件交给操作系统&#xff0c;按照机器码逐步执行&#xff0c;运行功能。 先看一个非常非常有趣的例子&#xff1a; class Father{ public:virtual void f(){cout<<"I am fat…...

汽车电子专有名词与相应技术

1.EEA &#xff08;Electronic & Electrical Architecture 电子电气架构&#xff09; EEA在宏观上概括为物理架构与逻辑架构的结合&#xff0c;微观上通过众多电子元器件的协同配合&#xff0c;或集成式或分布式的系统级电子电气架构&#xff0c;具体详见专栏 新能源汽车电…...

idea 没加载 provided的包

目录 前言解决方案 前言 我的版本是IntelliJ IDEA 2022.1.4 (Community Edition)&#xff0c;本地调试不知道为什么不加载provided的包。后来找到这篇文章https://youtrack.jetbrains.com/issue/IDEA-107048才知道这是个bug。不知道其他版本会不会出现这种问题。 解决方案 我…...

Hover:借贷新势力崛起,在经验与创新中找寻平衡

复苏中的Cosmos 如果让我选择一个最我感到可惜的区块链项目&#xff0c;我会选择Cosmos。 Cosmos最早提出并推动万链互联的概念&#xff0c;希望打通不同链之间的孤岛&#xff0c;彼时和另一个天王项目Polkadot号称跨链双雄。其跨链技术允许不同的区块链网络互相通信&#xf…...

软件设计原则-依赖倒置原则讲解以及代码示例

依赖倒置原则 一&#xff0c;介绍 1.前言 依赖倒置原则&#xff08;Dependency Inversion Principle&#xff0c;DIP&#xff09;是面向对象设计中的一个重要原则&#xff0c;由Robert C. Martin提出。 依赖倒置原则的核心思想是&#xff1a;高层模块不应该依赖于低层模块&…...

Linux--进程替换

1.什么是进程替换 在fork函数之后&#xff0c;父子进程各自执行代码的一部分&#xff0c;但是如果子进程想要执行一份全新的程序呢&#xff1f; 通过进程替换来完成&#xff0c;进程替换就是父子进程代码发生写时拷贝&#xff0c;子进程执行自己的功能。 程序替换就是通过特定的…...

【计算机网络】TCP协议

文章目录 1. TCP报文的结构2. TCP的发送缓冲区和接收缓冲区3. 确保可靠性序列号和确认序列号确认应答超时重传连接管理1️⃣三次握手建立连接2️⃣四次挥手断开连接 4. 提高性能流量控制滑动窗口拥塞控制延迟应答捎带应答 5. 面向字节流6. TCP/UDP对比 概念&#xff1a;TCP&…...

机器学习数据集:Kaggle

什么是Kaggle&#xff1f; Kaggle成立于2010年&#xff0c;是一个进行数据发掘和预测竞赛的在线平台。从公司的角度来讲&#xff0c;可以提供一些数据&#xff0c;进而提出一个实际需要解决的问题&#xff1b;从参赛者的角度来讲&#xff0c;他们将组队参与项目&#xff0c;针…...

软考 系统架构设计师系列知识点之设计模式(4)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之设计模式&#xff08;3&#xff09; 所属章节&#xff1a; 老版&#xff08;第一版&#xff09;教材 第7章. 设计模式 第2节. 设计模式实例 3. 行为型模式 行为型模式可以影响一个系统的状态和行为流。通过优化状态…...

PyCharm 安装 cx_Oracle 失败

我在PyCharm的终端用 pip安装cx_Oracle失败&#xff0c;报错情况如下&#xff1a; ERROR: Could not build wheels for cx_Oracle, which is required to install pyproject.toml-based projects 出错原因&#xff1a; python 的版本太高了&#xff0c;我的是3.11版本的&…...

解决Windows出现找不到mfcm90u.dll无法打开软件程序的方法

今天&#xff0c;我非常荣幸能够在这里与大家分享关于mfc90u.dll丢失的5种解决方法。在我们日常使用电脑的过程中&#xff0c;可能会遇到一些软件或系统错误&#xff0c;其中之一就是mfc90u.dll丢失。那么&#xff0c;mfc90u.dll究竟是什么文件呢&#xff1f;接下来&#xff0c…...

如何设计线程安全的 HashMap?

如何设计线程安全的 HashMap? HashMap 线程不安全的体现&#xff1a; 多线程下扩容死循环&#xff1a;JDK1.7中的 HashMap 使用头插法插入元素&#xff0c;在多线程的环境下&#xff0c;扩容的时候有可能导致环形链表的出现&#xff0c;形成死循环。因此&#xff0c;JDK1.8使…...

rpc汇总

1、什么是rpc rpc的应用&#xff0c;有哪些 Google 开源了 gRPC&#xff0c; Facebook 开源了 Thrift&#xff0c; Twitter 开源了 Finagle&#xff0c; 百度开源了bRPC&#xff0c; 腾讯开源了 Tars&#xff0c; 阿里开源了 Dubbo 和 HSF&#xff0c; 新浪开源了 Motan 等 gr…...

OpenCV学习(五)——图像基本操作(访问图像像素值、图像属性、感兴趣区域ROI和图像边框)

图像基本操作 5. 图像基本操作5.1 访问像素值并修改5.2 访问图像属性5.2 图像感兴趣区域ROI5.3 拆分和合并图像通道5.4 为图像设置边框&#xff08;填充&#xff09; 5. 图像基本操作 访问像素值并修改访问图像属性设置感兴趣区域&#xff08;ROI&#xff09;分割和合并图像 …...

指针仪表读数YOLOV8NANO

指针仪表读数YOLOV8 NANO 采用YOLOV8 NANO训练&#xff0c;标记&#xff0c;然后判断角度&#xff0c;得出角度&#xff0c;可以通过角度&#xff0c;换算成数据...