【JVM基础篇】Java垃圾回收器介绍

垃圾回收器(垃圾回收算法实现)

垃圾回收器是垃圾回收算法的具体实现。由于垃圾回收器分为年轻代和老年代,除了G1(既能管控新生代,也可以管控老年代)之外,新生代、老年代的垃圾回收器必须按照hotspot的要求成对组合进行使用(需要根据JDK的版本来选择相应的组合)

具体的组合关系如下:

在这里插入图片描述

JVM底层源码中,在某些特殊情况,CMS回收器会调用Serial Old回收器

Arthas查看所使用的垃圾回收器

不能直接看到使用了什么垃圾回收器,只能根据算法来推断

在这里插入图片描述

年轻代-Serial垃圾回收器

Serial是一种单线程串行回收年轻代的垃圾回收器。

在这里插入图片描述

回收年代和算法

  • 年轻代
  • 复制算法

优点

单CPU处理器下吞吐量非常出色

缺点

多CPU下吞吐量不如其他垃圾回收器(单线程,只使用了一个CPU),堆如果偏大会让用户线程处于长时间的等待

适用场景

Java编写的客户端程序或者硬件配置有限(CPU核数不多)的场景

如何使用

-XX:+UseSerialGC:新生代、老年代都使用串行回收器。

老年代-SerialOld垃圾回收器

SerialOld是Serial垃圾回收器的老年代版本,采用单线程串行回收

在这里插入图片描述

回收年代和算法

  • 老年代
  • 标记-整理算法

优点

单CPU处理器下吞吐量非常出色

缺点

多CPU下吞吐量不如其他垃圾回收器,堆如果偏大会让用户线程处于长时间的等待

适用场景

与Serial垃圾回收器搭配使用,或者在CMS特殊情况下使用

如何使用

-XX:+UseSerialGC:新生代、老年代都使用串行回收器。

年轻代-ParNew垃圾回收器

ParNew垃圾回收器本质上是对Serial在多CPU下的优化,使用多线程进行垃圾回收

在这里插入图片描述

回收年代和算法:

  • 年轻代
  • 复制算法

优点

  • 多CPU处理器下停顿时间较短

缺点

  • 吞吐量和停顿时间不如G1,所以在JDK9之后不建议使用

适用场景

  • JDK8及之前的版本中,与CMS老年代垃圾回收器搭配使用

如何使用

  • -XX:+UseParNewGC:新生代使用ParNew回收器, 老年代使用串行回收器

在这里插入图片描述

老年代-CMS(Concurrent Mark Sweep)垃圾回收器

CMS垃圾回收器关注的是系统的暂停时间(尽量减少STW,优化用户体验),允许用户线程和垃圾回收线程在某些步骤中同时执行,减少了用户线程的等待时间。

回收年代和算法

  • 老年代
  • 标记清除算法

优点

  • 系统由于垃圾回收出现的停顿时间较短,用户体验好

缺点

1、内存碎片问题

2、退化问题(在某些特定情况,会退化为SerialOld这种单线程回收器)

3、浮动垃圾问题(回收过程,有的垃圾回收不掉)

适用场景

大型的互联网系统中用户请求数据量大、频率高的场景,比如订单接口、商品接口等

使用

XX:+UseConcMarkSweepGC,可以分别设置年轻代和老年代的回收器

在这里插入图片描述

在这里插入图片描述

CMS执行步骤

  1. 初始标记,用极短的时间标记出GC Roots能直接关联到的对象
  2. 并发标记, 标记所有的对象,用户线程不需要暂停。(虽然并发标记是和用户线程一起执行,但是如果并发标记占用的资源较高,也会影响用户线程)
  3. 重新标记(并发),由于并发标记阶段有些对象会发生了变化,存在错标(用的对象本来是存活的,标记之后,用户线程把它变得不存活了,导致错标)、漏标(因为是并发的,可能有的对象是用户线程刚刚创建出来的,就会导致漏标)等情况,需要重新标记。
  4. 并发清理,清理死亡的对象,用户线程不需要暂停。

注:只有初始标记、重新标记阶段会出现STW

在这里插入图片描述

缺点:

1、CMS使用了标记-清除算法,在垃圾收集结束之后会出现大量的内存碎片,为了不影响对象的分配,CMS会在Full GC时进行碎片的整理。这样会导致用户线程暂停,可以使用-XX:CMSFullGCsBeforeCompaction=N 参数(默认0)调整N次Full GC之后再整理

2.、无法处理在并发清理过程中产生的“浮动垃圾”,不能做到完全的垃圾回收(在本次清理的过程中,用户线程并发创建了一些对象,但是很快没有再使用,这些对象在这次清理中没有得到回收,需要等到下一次清理,所以称这些为浮动垃圾)。

3、如果老年代内存不足无法分配对象,CMS就会退化成Serial Old单线程回收老年代。

并发线程数:

在CMS中并发阶段运行时的线程数可以通过-XX:ConcGCThreads参数设置,由系统计算得出,计算公式为(-XX:ParallelGCThreads定义的线程数 + 3) / 4, ParallelGCThreads是STW停顿之后的并行线程数

ParallelGCThreads是由处理器核数决定的:

1、当cpu核数小于8时,ParallelGCThreads = CPU核数

2、否则 ParallelGCThreads = 8 + (CPU核数 – 8 )*5/8

我的电脑上逻辑处理器有12个,所以ParallelGCThreads = 8 + (12 - 8)* 5/8 = 10,ConcGCThreads = (-XX:ParallelGCThreads定义的线程数 + 3) / 4 = (10 + 3) / 4 = 3

在这里插入图片描述

最终可以得到这张图:

在这里插入图片描述

并发标记和并发清理阶段,会使用3个线程并行处理。重新标记阶段会使用10个线程处理。由于CPU的核心数有限,并发阶段会影响用户线程执行的性能。

在这里插入图片描述

年轻代-Parallel Scavenge垃圾回收器

Parallel Scavenge是JDK8默认的年轻代垃圾回收器,多线程并行回收关注的是系统的吞吐量。为了拉高吞吐量,PS会自动调整堆内存大小(调整新生代、老年代内存大小、晋升的阈值)

在这里插入图片描述

回收年代和算法

  • 年轻代
  • 复制算法

优点

  • 吞吐量高,而且支持手动设置参数控制吞吐量。为了提高吞吐量,虚拟机会动态调整堆的参数(用户只需要设置吞吐量,不需要设置内存大小等其他参数)

缺点

  • 不能保证单次的停顿时间,但是支持设置STW时间

适用场景

  • 后台任务,不需要与用户交互,并且容易产生大量的对象。比如:大数据的处理,大文件导出

常用参数

Parallel Scavenge允许手动设置最大暂停时间和吞吐量。Oracle官方建议在使用这个组合时,不要设置堆内存的最大值,垃圾回收器会根据最大暂停时间和吞吐量自动调整内存大小。

  • 最大暂停时间,-XX:MaxGCPauseMillis=n 设置每次垃圾回收时的最大停顿毫秒数
  • 吞吐量,-XX:GCTimeRatio=n 设置吞吐量为n(用户线程执行时间 = n/(n + 1))
  • 自动调整内存大小, -XX:+UseAdaptiveSizePolicy设置可以让垃圾回收器根据吞吐量和最大停顿的毫秒数自动调整内存大小,这个参数默认是开启的(Oracle建议使用PS组合的时候,不要设置堆内存的最大值,让垃圾回收器自动调整)

注:最大暂停时间和吞吐量这两个指标是冲突的,垃圾回收器会尽量满足最大暂停时间(有时候设置得太小,是没办法满足的,会超出所设置得最大暂停时间),牺牲吞吐量。如果要同时设置最大暂停时间和吞吐量,要多做测试,让它们比较协调

老年代-Parallel Old垃圾回收器

Parallel Old是为Parallel Scavenge收集器设计的老年代版本,利用多线程并发收集。

在这里插入图片描述

回收年代和算法

  • 老年代
  • 标记-整理算法(其实是标记+清除+整理)

优点

  • 并发收集,在多核CPU下效率较高

缺点

  • 暂停时间会比较长

适用场景

  • 与Parallel Scavenge配套使用

如何使用

JDK8设置参数,就是默认使用该回收器

参数:-XX:+UseParallelGC-XX:+UseParallelOldGC可以使用Parallel Scavenge + Parallel Old这种组合。
在这里插入图片描述

在这里插入图片描述

测试

-XX:+PrintFlagsFinal:可以在程序启动的时候打印所有配置项的最终值,可以看看自动调整功能有没有开启

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** 垃圾回收器案例3*/
//-XX:+UseSerialGC -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX:+PrintGCDetails -verbose:gc -XX:+PrintFlagsFinal
//-XX:+UseParNewGC  -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX:+PrintGCDetails -verbose:gc
//-XX:+UseConcMarkSweepGC
//-XX:+UseG1GC   -Xmn8g -Xmx16g -XX:SurvivorRatio=8  -XX:+PrintGCDetails -verbose:gc MaxGCPauseMillis
//-XX:+PrintFlagsFinal  -XX:GCTimeRatio = 19  -XX:MaxGCPauseMillis=10 -XX:+UseAdaptiveSizePolicy
public class GcDemo2 {public static void main(String[] args) throws IOException {int count = 0;List<Object> list = new ArrayList<>();while (true){//System.out.println(++count);if(count++ % 10240 == 0){list.clear();}
//            byte[] bytes = new byte[1024 * 1024 * 1];list.add(new byte[1024 * 1024 * 1 / 2]);
//            System.gc();}}
}

【测试最大暂停时间=10】

在这里插入图片描述

内存大小如下:

在这里插入图片描述

【测试最大暂停时间=1】

在这里插入图片描述

在这里插入图片描述

结论:堆内存越小,垃圾回收暂停时间越短

G1(Garbage First)垃圾回收器(极力推荐)

JDK9之后默认的垃圾回收器是G1(Garbage First)垃圾回收器。

  • Parallel Scavenge关注吞吐量,允许用户设置最大暂停时间 ,但是会减少年轻代可用空间的大小。
  • CMS关注暂停时间,但是吞吐量方面会下降。
  • 而G1设计目标就是将上述两种垃圾回收器的优点融合:

JDK9之后强烈建议使用G1垃圾回收器。(在JDK7、8上,G1可能不是很成熟,要慎重考虑)

G1出现之前的垃圾回收器,年轻代和老年代一般是连续的,如下图:

在这里插入图片描述

G1内存结构发生了变化:G1的整个堆会被划分成多个大小相等的区域,称之为区Region,区域不要求是连续的。分为Eden、Survivor、Old区。Region的大小通过堆空间大小/2048计算得到,也可以通过参数-XX:G1HeapRegionSize=32m指定(其中32m指定region大小为32M),Region size必须是2的指数幂,取值范围从1M到32M。

在这里插入图片描述

G1垃圾回收有两种方式

1、年轻代回收(Young GC)

2、混合回收(Mixed GC)

年轻代回收(Young GC)

只回收年轻代,回收Eden区和Survivor区中不用的对象。会导致STW,G1中可以通过参数

-XX:MaxGCPauseMillis=n(默认200) 设置每次垃圾回收时的最大暂停时间毫秒数,G1垃圾回收器会尽可能地保证暂停时间。

【Young GC步骤】

1、新创建的对象会存放在Eden区。当G1判断年轻代区不足(max默认60%,如果年轻代的内存占了总堆的60%以上,就要Young GC),无法分配对象时需要回收时会执行Young GC。

在这里插入图片描述

2、标记出Eden和Survivor区域中的存活对象,

3、根据配置的**最大暂停时间选择某些区域(和其他回收器的区别:其他回收器会回收负责的所有区域)**将存活对象复制到一个新的Survivor区中(年龄+1)(使用复制算法,不会产生内存碎片),清空这些区域。

在这里插入图片描述

在这里插入图片描述

G1在进行Young GC的过程中会去记录每次垃圾回收时每个Eden区和Survivor区的平均耗时,以作为下次回收时的参考依据。这样就可以根据配置的最大暂停时间计算出本次回收时最多能回收多少个Region区域了。比如-XX:MaxGCPauseMillis=n(默认200),每个Region回收耗时40ms,那么这次回收最多只能回收4个Region。

4、后续Young GC时与之前相同,只不过Survivor区中存活对象会被搬运到另一个Survivor区。

在这里插入图片描述

在这里插入图片描述

5、当某个存活对象的年龄到达阈值(默认15),将被放入老年代。原来的Survivor中年龄没有到达15的对象,还是会迁移到新的Survivor中。

在这里插入图片描述

6、部分对象如果大小超过Region的一半,会直接放入老年代,这类老年代被称为Humongous(翻译:巨大的)区。比如堆内存是4G,每个Region是2M,只要一个大对象超过了1M就被放入Humongous区,如果对象过大会横跨多个Region(一个Region放不完)

在这里插入图片描述

7、多次回收之后,会出现很多Old老年代区,此时总堆占有率达到阈值时

-XX:InitiatingHeapOccupancyPercent默认45%)会触发混合回收Mixed GC,回收所有年轻代和部分老年代的对象以及大对象区。采用复制算法来完成。

在这里插入图片描述

在这里插入图片描述

混合回收(Mixed GC)

混合回收分为如下步骤,看起来和CMS差不多,但是步骤里面都是有区别的:

  • 初始标记(initial mark)
  • 并发标记(concurrent mark)
  • 最终标记(remark或者Finalize Marking):只管漏标,不管新创建、不再关联的对象。这里使用的算法远比CMS的快
  • 并发清理(cleanup):G1对老年代的清理会选择存活度最低的区域来进行回收(A区:100个对象只存活1个;B区:100个对象存活99个;G1选择回收A区),这样可以保证回收效率最高,这也是G1(Garbage first)名称的由来。最后清理阶段使用复制算法,不会产生内存碎片。

在这里插入图片描述

在这里插入图片描述

注意:**如果清理过程中发现没有足够的空Region存放转移的对象,会出现Full GC,**单线程执行标记-整理算法,此时会导致用户线程的暂停,影响用户的正常使用。所以尽量保证应该用的堆内存有一定多余的空间,如果堆内存的占用比较高,就要考虑优化。

在这里插入图片描述

如何使用G1垃圾回收器

参数1: -XX:+UseG1GC 打开G1的开关,JDK9之后默认不需要打开

参数2:-XX:MaxGCPauseMillis=毫秒值 最大暂停的时

回收年代和算法

  • 年轻代+老年代
  • 复制算法

优点

  • 支持巨大的堆空间回收,并有较高的吞吐量。对比较大的堆延迟可控,如超过6G的堆回收时
  • 不会产生内存碎片
  • 并发标记的SATB算法效率高,比CMS的算法效率高
  • 支持多CPU并行垃圾回收
  • 允许用户设置最大暂停时间

缺点

  • JDK8的早期版本还不够成熟

适用场景

  • JDK8最新版本、JDK9之后建议默认使用

测试

使用以下代码测试g1垃圾回收器,打印出每个阶段的时间:

在这里插入图片描述

package chapter04.gc;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** 垃圾回收器案例3*/
//-XX:+UseG1GC   -Xmn8g -Xmx16g -XX:SurvivorRatio=8  -XX:+PrintGCDetails -verbose:gc 
public class GcDemo2 {public static void main(String[] args) throws IOException {int count = 0;List<Object> list = new ArrayList<>();while (true){//System.out.println(++count);if(count++ % 10240 == 0){list.clear();}
//            byte[] bytes = new byte[1024 * 1024 * 1];list.add(new byte[1024 * 1024 * 1 / 2]);
//            System.gc();}}
}

每个region大小为2m,一共有84个young区,26个幸存者区。

在这里插入图片描述

初始标记花了0.0478秒,初始标记是伴随着年轻代回收的,0.0478秒是两个操作的总时间
在这里插入图片描述

在这里插入图片描述

并发标记总共耗时10ms,不会产生STW。

在这里插入图片描述

最终标记,效率较高

在这里插入图片描述

清理阶段

在这里插入图片描述

垃圾回收器总结

垃圾回收器的组合关系虽然很多,但是针对几个特定的版本,比较好的组合选择如下:

  • JDK8及之前:
    • ParNew + CMS(关注暂停时间)
    • Parallel Scavenge + Parallel Old (关注吞吐量)
    • G1(JDK8之前不建议,较大堆并且关注暂停时间)
  • JDK9之后:G1(默认)。从JDK9之后,由于G1日趋成熟,JDK默认的垃圾回收器已经修改为G1,所以强烈建议在生产环境上使用G1。G1的实现原理将在《原理篇》中介绍,更多前沿技术ZGC(最新的垃圾回收器)、GraalVM将在《高级篇》中介绍。

几个问题

Java中有哪几块内存需要垃圾回收?

在这里插入图片描述

方法区回收,Java程序员少关注

在这里插入图片描述

在这里插入图片描述

有哪几种常见的引用类型?

  • 强引用,最常见的引用方式,由可达性分析算法来判断
  • 软引用,对象在没有强引用情况下,内存不定时会回收
  • 弱引用,对象在没有强引用情况下,会直接回收
  • 虚引用,通过虚引用知道对象被回收了
  • 终结器引用,对象回收时可以自救,不建议使用

有哪几种常见的垃圾回收算法?

在这里插入图片描述

常见的垃圾回收器有哪些?

  • Serial+Serial Old:单线程回收,适用于单核CPU场景
  • ParNew+CMS:暂停时间较短,适用于大型互联网应用中与用户交互的部分
  • Paraller Scavenge+Parallel Old:吞吐量高,适用于后台进行大量数据操作
  • G1:适用于较大堆,具有可控暂停时间

文章说明

该文章是本人学习 黑马程序员 的学习笔记,文章中大部分内容来源于 黑马程序员 的视频黑马程序员JVM虚拟机入门到实战全套视频教程,java大厂面试必会的jvm一套搞定(丰富的实战案例及最热面试题),也有部分内容来自于自己的思考,发布文章是想帮助其他学习的人更方便地整理自己的笔记或者直接通过文章学习相关知识,如有侵权请联系删除,最后对 黑马程序员 的优质课程表示感谢。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql5.7并发插入死锁问题

死锁的产生条件 互斥、请求和保持、不可剥夺、循环等待 MySQL锁类型 死锁复现 环境&#xff1a;Mysql 5.7版本&#xff0c;Innodb引擎&#xff0c;可重复度隔离级别 并发场景下使用duplicate key update插入或更新数据可能会造成死锁&#xff0c;下面就产生死锁的条件进行模…

用QFramework重构飞机大战(Siki Andy的)(上)(00-05 到游戏界面之前的所有面板)

GitHub // 官网的 全民飞机大战&#xff08;第一季&#xff09;-----框架设计篇&#xff08;Unity 2017.3&#xff09; 全民飞机大战&#xff08;第二季&#xff09;-----游戏逻辑篇&#xff08;Unity 2017.3&#xff09; 全民飞机大战&#xff08;第三季&#xff09;-----完善…

LabVIEW在图像处理中的应用

abVIEW作为一种图形化编程环境&#xff0c;不仅在数据采集和仪器控制领域表现出色&#xff0c;还在图像处理方面具有强大的功能。借助其Vision Development Module&#xff0c;LabVIEW提供了丰富的图像处理工具&#xff0c;广泛应用于工业检测、医学影像、自动化控制等多个领域…

C语言 -- 扫雷游戏

C语言 – 扫雷游戏 游戏规则&#xff1a; 给定一个棋盘&#xff0c;玩家需要排查出所有隐藏的雷&#xff0c;也就是选择出所有不是雷的地方。 玩家选择位置&#xff0c;若此处有雷&#xff0c;玩家被炸死&#xff0c;游戏结束&#xff1b; 若此处无雷&#xff0c;此处提示周围一…

【零基础】学JS

喝下这碗鸡汤 “知识就是力量。” - 弗朗西斯培根 1.三元运算符 目标:能利用三元运算符执行满足条件的语句 使用场景:其实是比if双分支更简单的写法&#xff0c;可以使用三元表达式 语法&#xff1a;条件 ? 满足条件的执行代码 : 不满足条件执行的代码 接下来用一个小案例来展…

【瑞数补环境实战】某网站Cookie补环境与后缀分析还原

文章目录 1. 写在前面2. 特征分析3. 接口分析3. 补JS环境4. 补后缀参数 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走…

ubuntu22.04+pytorch2.3安装PyG图神经网络库

ubuntu下安装torch-geometric库&#xff0c;图神经网络 开发环境 ubuntu22.04 conda 24.5.0 python 3.9 pytorch 2.0.1 cuda 11.8 pyg的安装网上教程流传着许多安装方式&#xff0c;这些安装方式主要是&#xff1a;预先安装好pyg的依赖库&#xff0c;这些依赖库需要对应上pyth…

代码随想录 数组部分+代码可在本地编译器运行

代码随想录 数组部分&#xff0c;代码可在本地编译器运行 文章目录 数组理论基础704.二分查找题目&#xff1a;思路二分法第一种写法二分法第二种写法 代码 27.移除元素题目&#xff1a;思路-双指针法代码 977.有序数组的平方题目思路-双指针代码 209.长度最小的子数组题目&am…

Lua语言入门

目录 Lua语言1 搭建Lua开发环境1.1 安装Lua解释器WindowsLinux 1.2 IntelliJ安装Lua插件在线安装本地安装 2 Lua语法2.1 数据类型2.2 变量全局变量局部变量命名规范局部变量作用域 2.3 注释单行注释多行注释 2.4 赋值2.5 操作符数学操作符比较操作符逻辑操作符连接操作符取长度…

安卓虚拟位置修改1.25beta支持路线模拟、直接定位修改

导语:更新支持安卓14/15&#xff0c;支持路线模拟、直接定位修改&#xff0c;仅支持单一版本 无root需根据教程搭配下方链接所提供的虚拟机便可进行使用 有root且具备XP环境可直接真机运行 如你有特殊需求 重启问题设置打开XP兼容 针对具有虚拟机检测的软件 建议如下 度娘搜索…

Python结合MobileNetV2:图像识别分类系统实战

一、目录 算法模型介绍模型使用训练模型评估项目扩展 二、算法模型介绍 图像识别是计算机视觉领域的重要研究方向&#xff0c;它在人脸识别、物体检测、图像分类等领域有着广泛的应用。随着移动设备的普及和计算资源的限制&#xff0c;设计高效的图像识别算法变得尤为重要。…

机器学习原理之 -- 神经网络:由来及原理详解

神经网络&#xff08;Neural Networks&#xff09;是受生物神经系统启发而设计的一类计算模型&#xff0c;广泛应用于图像识别、语音识别、自然语言处理等领域。其基本思想是通过模拟人脑神经元的工作方式&#xff0c;实现对复杂数据的自动处理和分类。本文将详细介绍神经网络的…

Http Json参数到x-www-form-urlencoded参数的在线转换工具

Json参数到x-www-form-urlencoded参数的在线转换工具

本周23个Github有趣项目llama-agents等

23个Github有趣的项目、工具和库 1、Positron 下一代数据科学 IDE。 您使用 VS Code 进行数据科学&#xff08;Python 或 R&#xff09;&#xff0c;但希望它包含专用控制台、变量窗格、数据浏览器和其他用于特定数据工作的功能。您使用 Jupyterlab 进行数据科学&#xff08;…

求职成功率的算法,与葫芦娃救爷爷的算法,有哪些相同与不同

1 本节概述 通过在B站百刷葫芦娃这部儿时剧&#xff0c;我觉得可以从中梳理出一些算法&#xff0c;甚至可以用于求职这个场景。所以&#xff0c;大家可以随便问我葫芦娃的一些剧情和感悟&#xff0c;我都可以做一些回答。 2 葫芦娃救爷爷有哪些算法可言&#xff1f; 我们知道…

AE的首选项设置

打开AE,点击 编辑->首选项->常规 显示 点击“所有关键帧”&#xff0c;这样显示路径就会显示所有关键帧 导入 将序列素材改为25帧每秒&#xff0c;作为以后制作的默认 媒体和磁盘缓存 根据个人需求选择磁盘缓存的文件夹&#xff0c;如果d盘空间充足&#xff0c;就改成…

Linux——进程间通信一(共享内存、管道、systrem V)

一、进程间通信介绍 1.1、进程间通信的概念和意义 进程间通信(IPC interprocess communication)是一组编程接口&#xff0c;让不同进程之间相互传递、交换信息(让不同的进程看到同一份资源) 数据传输:一个进程需要将它的数据发送给另外一个进程 资源共享:多个进程之间共享同样…

WY-35A4T三相电压继电器 导轨安装 约瑟JOSEF

功能简述 WY系列电压继电器是带延时功能的数字式交流电压继电器。 可用于发电机&#xff0c;变压器和输电线的继电保护装置中&#xff0c;作为过电压或欠电压闭锁的动作元件 LCD实时显示当前输入电压值 额定输入电压Un:100VAC、200VAC、400VAC产品满足电磁兼容四级标准 产品…

开放式耳机哪个牌子好?悠律、漫步者、韶音全面对比与推荐

对于现在的无线耳机市场而言&#xff0c;开放式耳机迎来的真正的大爆发&#xff0c;关键的是它采用了定向传声方式&#xff0c;我们在运动时除了可以感受到音乐带来的快乐外&#xff0c;还能时刻保持对外界环境音的警觉。 今天&#xff0c;我们将为大家详细对比推荐三款备受瞩…

Docker 容器网络及其配置说明

Docker 容器网络及其配置说明 docker容器网络docker的4种网络模式bridge 模式container模式host 模式none 模式应用场景 docker 容器网络配置Linux 内核实现名称空间的创建创建 Network Namespace操作 Network Namespace 转移设备veth pair创建 veth pair实现 Network Namespac…