【jvm系列-09】垃圾回收底层原理和算法以及JProfiler的基本使用

news2024/11/17 17:51:28

JVM系列整体栏目


内容链接地址
【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460
【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963
【三】运行时私有区域之虚拟机栈、程序计数器、本地方法栈https://blog.csdn.net/zhenghuishengq/article/details/129684076
【四】运行时数据区共享区域之堆、逃逸分析https://blog.csdn.net/zhenghuishengq/article/details/129796509
【五】运行时数据区共享区域之方法区、常量池https://blog.csdn.net/zhenghuishengq/article/details/129958466
【六】对象实例化、内存布局和访问定位https://blog.csdn.net/zhenghuishengq/article/details/130057210
【七】执行引擎,解释器、JIT即时编译器https://blog.csdn.net/zhenghuishengq/article/details/130088553
【八】精通String字符串底层机制https://blog.csdn.net/zhenghuishengq/article/details/130154453
【九】垃圾回收底层原理和算法以及JProfiler的基本使用https://blog.csdn.net/zhenghuishengq/article/details/130261481

垃圾回收篇底层原理及相关算法

  • 一,垃圾回收篇底层原理
    • 1,垃圾回收概述
      • 1.1,什么是垃圾
      • 1.2,为什么需要gc
      • 1.3,java垃圾回收机制
    • 2,垃圾回收算法
      • 2.1,垃圾标记阶段
        • 2.1.1,引用计数算法
        • 2.2.2,可达性分析算法
    • 3,JProfiler查看GC Root
    • 4,垃圾回收相关算法
      • 4.1,标记清除算法
      • 4.2,复制算法
      • 4.3,标记整理算法
      • 4.4,三种算法总结
    • 5,垃圾回收相关概念
      • 5.1,System.gc() 的理解
      • 5.2,内存溢出和内存泄漏
        • 5.2.1,内存溢出(OOM)
        • 5.2.2,内存泄漏
      • 5.3,Stop The World
      • 5.4,引用

一,垃圾回收篇底层原理

1,垃圾回收概述

1.1,什么是垃圾

垃圾收集,并不是Java语言的产物,早在1960年,第一门使用内存动态分配和垃圾收集技术的Lisp语言诞生。垃圾回收机制也是Java的招牌能力,极大地提高了开发效率。因此在面对垃圾回收时,需要解决三个主要的问题:哪些内存需要回收、什么时候回收、如何回收?

在这里插入图片描述

垃圾:指的是在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。如创建了某个对象,引用该对象的变量是存储在虚拟机栈的栈帧中,随着入栈出栈该栈帧被销毁,那么栈帧中引用该对象的局部变量变量也被销毁,此时没有任何变量引用着刚刚创建的对象,那么该对象就会变成垃圾,等待回收。

1.2,为什么需要gc

首先如果垃圾不回收,内存很容易被消耗完,在面对一个大系统的时候,没有GC就很难保证应用程序正常运行。

如果不及时的对内存中的垃圾进行回收, 那么这些对象所占的内存空间会一直保留到应用程序结束,被保留的空间无法被其他对象使用,甚至会出现内存溢出的情况。

1.3,java垃圾回收机制

java内部通过自动内存管理的方式,无需开发人员手动参与内存的分配和回收,这样可以降低内存泄漏和内存溢出的问题,从而省去繁重的内存管理,可以更加专注的进行业务开发。

然而自动内存管理就如同一个黑匣子,如果过度依赖自动化,那么就会弱化开发人员在程序出现内存溢出时定位问题和解决问题的能力。因此当需要排查各种内存溢出、内存泄漏等问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,就需要对这个垃圾回收进行必要的监控和调节

在进行垃圾回收时,主要针对的是Java堆的这个区域。从次数上来说,频繁的收集Young区,较少的收集Old区域,基本不动方法区(永久代或者元空间)

2,垃圾回收算法

在这垃圾回收的算法中,主要是做了两件事情:一件是找出垃圾,另一件是清除垃圾

2.1,垃圾标记阶段

垃圾标记阶段主要就是找出垃圾,用于判断对象是否存活。堆中几乎所有的对象都存储在堆中,在GC执行垃圾回收之前,需要先区分哪些是存活的对象,哪些是已经死亡的对象。只有被标记已经死亡的对象,GC才会在执行垃圾回收时,才会释放掉其占用的内存,这个阶段就被称为垃圾标记阶段

在JVM内部,判断对象是否存活主要是通过两种方式:引用计数算法可达性分析算法

2.1.1,引用计数算法

这种算法就是会为每一个对象保存一个引用计数器属性,如对于一个对象A,只要有任何一个对象引用了A,那么这个A对应的计数器就会加1,当引用失效计数器就会减1。只有引用计数器的值为0时,表示不再被任何变量引用,那么该对象就会被标记,后续会根据是否标记进行回收。

优点是实现比较简单,垃圾对象便于识别,并且其效率比较高;缺点是需要单独的字段存储计数器,需要一定的空间开销,并且计数器需要加减运算操作,增加了时间开销,最主要的是无法处理循环引用的问题,因此Java并没有选择这种算法。

public class A{
    public A a = null;
    List<A> list = new ArrayList();
    public static void main(String[] args) {
        A objectA = new A();
        A objectB = new A();
        //这两个对象相互引用,俩个计数器都+1,导致无法回收
        objectA.a = objectB;
        objectB.a = objectA;
    }
}

2.2.2,可达性分析算法

相对于引用计数器而言,可达性分析算法不仅具有简单和执行高效等特点,更重要的是可以有效地解决这个循环引用的问题,从而防止出现内存泄漏

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VnXrU94q-1681959175717)(img/1681701973152.png)]

通过上图可知,可达性分析算法是以根对象集合为起点,按照从上到下的方式搜索根对象集合所连接的目标是否可达,内存中的存活对象都会被根对象集合直接或者间接连接着,如GC roots和obj1是直接连接着的,和2,3,4是间接连接着的,这整个连接路径被称为引用链。如果目标对象没有任何引用链相连,如6,7,8,则是不可达的,就意味着该对象以及死亡,可以标记为垃圾对象。

在java中,常被用作GC对象的有以下几种:方法中的参数、局部变量、静态属性、字符串常量池引用、同步锁持有的对象、基本数据类型对应的Class对象、异常对象、本地缓存等等。

在使用这个可达性分析算法来判断内存是否可以进行回收,在分析工作时必须在一个能保障一致性的快照中进行,不允许在分析时出现动态的垃圾的增加等,这样才能保证分析结果的准确性。但是也正是因为这个快照的问题,让stw的出现不可避免。

3,JProfiler查看GC Root

查看GC Root有好几种方式,如使用MAT等,但是MAT要涉及到eclipse这些,因此废弃MAT。这里主要是通过这个 JProfiler 这个工具,可以直接在idea中搜索这个插件安装,然后重启idea即可。

在这里插入图片描述

除了这里安装之外,最好再安装一个 .exe 的可执行文件,可以参考黄莹这位大佬写的,这里面有免费JProfiler下载: https://blog.csdn.net/weixin_42311968/article/details/120726106 下载完之后一直点下去,安装,我这里是先使用免费10天的。

安装完成之后,再回到idea,点击右上角的JProfile的图标

在这里插入图片描述

然后在提示框中,输入刚刚 .exe安装路径下面的bin目录下面的 .exe,然后保存即可,再次点击就可以直接使用了

//如我这边安装目录是在D盘下,因此找到这个路径下面的 JProfiler.exe 文件即可
D:\environment\jprofiler\jprofiler11\bin

然后下一步也是那个大佬里面写的,将JVM exit action的参数改成如以下图所示即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9H08THq7-1681959175720)(img/1681808812105.png)]

再点击ok之后,那么这个画面就有了,工具基本就可以使用了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9N6FxTNm-1681959175721)(img/1681809199238.png)]

一段时间之后,就会出现如下画面,其画面是动态的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3KeL8hja-1681959175721)(img/1681810080320.png)]

在Live memory下的All Objects中监视着所有的内存情况,和之前谈到的JVisualVM的功能都是类似的,如之前谈到查看这个字符串常量池到底存在哪就是通过这个方式举的例子。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2hyQPQKg-1681959175722)(img/1681809814749.png)]

如果出现OOM,可以直接通过查看这个Heap Walker目录下的对象信息,来确定是哪个对象发生的OOM,以及是否出现大对象等问题。

4,垃圾回收相关算法

上面讲述了两种方式找出垃圾,接下来就需要将找出的垃圾给清除掉,释放无用对象的内存空间,以便有足够的可用内存为新对象的分配。在jvm中,比较常见的三种垃圾回收算法有:标记清除算法、复制算法、标记压缩算法

4.1,标记清除算法

当堆中有效的内存空间被耗尽的时候,会停止整个程序,简称stw(stop the world),这样可以防止在标记回收的和清除的时候又有新的垃圾出现。

在这里面主要进行两箱工作,第一项是标记,第二项是清除。标记是从根节点开始,标记所有的引用对象,一般是可达对象;清除是从头到尾线性遍历,发现某个对象没有标记为可达对象,则将其回收。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mT2u9H5O-1681959175723)(img/1681871396273.png)]

如上图,绿色部分表示存活对象,黑色表示垃圾对象,白色表示空闲对象,然后从根节点出发,判断对象是否可达,从而确定对象是否需要被回收,最后将黑色对应的对象回收即可,从而实现这个标记清除算法。

该算法的优点是简单易理解。但是缺点也很明显,效率较低;并且在GC的时候,需要停止整个应用程序(stw),用户体验差;最主要的是会产生大量的内存碎片,因此在内部需要维护一个空闲列表。这里的清除并不是直接将对象清除,而是将要清除对象的地址加入到空闲列表里面,然后记录指向要被清除对象的指针,后面来新的对象之后,则将这个空闲列表记录的指针指向新来的这个对象。

4.2,复制算法

针对标记清除的算法的缺陷,如会产生内存碎片,因此这种复制算法诞生。

其核心思想就是将内存空间分成两块,每次只使用其中的一块,在垃圾回收的时候将正在使用的内存中的存活的对象复制到未被使用的内存中,之后再将正在使用的内存中的对象清除,再交换两个内存的角色,最后完成垃圾回收

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YmNZmPj3-1681959175723)(img/1681879548891.png)]

这里的复制是将完整的对象复制,在新生代中存活区的s0区和s1区就是实现了这种算法,经典以空间换时间。并且在后期分配对象时,可以直接使用指针碰撞算法。

复制算法的优点是:没有标记和清除的过程,简单实现,运行高效,并且解决了碎片化的问题。

复制算法的缺点是:需要两倍的内存空间,如果垃圾多,那么需要移动的次数也多,影响效率。

4.3,标记整理算法

复制算法效率虽然高,但是更加的适合新生代中使用,因为那里的对象朝生夕死,那么需要复制移动的对象就不会太多,也就不会太影响效率。但是复制算法不适合在老年代使用,因为里面的对象基本是存活的,那么真要复制移动起来,那么就会严重影响效率,那么这种算法的代价就会比较高。

而标记清除算法会产生垃圾碎片,显然也不能在这个老年代使用,因为如果出现一个大对象这就可能出现放不下的情况,因此就出现了一种新的算法,标记整理法。这种算法就是在标记清除这种算法之上进行了优化的一种算法,从而解决这种内存碎片的问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DtDj66pf-1681959175724)(img/1681885073399.png)]

这种核心思想就是通过根节点开始标记所有能被引用的对象,然后将所有存活的对象按顺序排放,再清理掉没被引用的垃圾。标记整理算法的最终效果就是等同于标记清除之后,再进行一次碎片管理,一次也可以称为 标记-清除-压缩 算法,该算法也不需要使用空闲列表来记录碎片。

标记整理算法的优点是:解决标记清除碎片化问题,复制算法空间问题

标记整理算法的优点是:效率低于复制算法,移动对象的同时需要移动对象引用,移动过程需要stw

4.4,三种算法总结

从效率上来说,复制算法的效率最高,但是会浪费大量的内存。因此兼顾速度,空间开销,是否需要移动对象三个指标来说,标记整理算法相对来说更为稳定,但是效率上不尽人意,因为他比复制算法多了一个标记阶段,比标记清除算法多了一个整理内存的阶段。

5,垃圾回收相关概念

5.1,System.gc() 的理解

默认情况下,通过这个System.gc()的调用,就会显式的触发这个Full GC,同时对这个老年代和新生代进行回收,尝试释放被丢弃的对象所占用的内存。

但是这个System.gc()会调用一个附带的免责声明,就是说这个确实可以触发这个Full GC,但是垃圾回收器会不会做出具体的响应,已经响应的时间是否即时很难保证,有可能并不会响应这次请求,也可能在很长时间后才触发,导致想清除的对象复活或者迟迟不能回收导致OOM的情况。

垃圾回收一般是可以自动进行的,无需手动触发,否则就太过于麻烦了。但是在测试性能的基准的时候,可以在运行期间调用这个System.gc()。

/**
 * @author zhenghuisheng
 * @date : 2023/4/19
 */
public class Test {
    public static void main(String[] args) {
        User user = new User();
        //提醒Jvm进行垃圾回收
        System.gc();
        //强制执行
        //System.runFinalization();
    }
	
    //触发了垃圾回收就会调用这个finalize()
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("触发了垃圾回收");
    }
}

通过上述代码可以得知,在System.gc()之后,有时会触发有时不会触发这个full GC,但是使用这个System.runFinalization()方法时可以保证一定会触发这个 FULL GC的,因为他是强制执行的。

5.2,内存溢出和内存泄漏

5.2.1,内存溢出(OOM)

由于GC的技术一直不断地完善和发展,因此在一般的情况下是不会出现OOM的,除非应用程序所占的内存增长速度非常快,造成垃圾回收已经跟不上内存消耗的速度,这样才可能出现OOM。GC会进行各种年龄段的垃圾回收,在出现OOM之前也会触发一次FULL GC的操作,这时候会回收大量的内存,如果在回收大量的内存之后还不够用,那么就会出现OOM的问题。在java文档中对OutOfMemoryError的解释是这样的:没有空闲内存,并且垃圾收集器也无法提供更多的内存

而内存不够的原因,有可能是Java虚拟机堆内存设置的不够;也可能是创建了大量的大对象,并且对象被引用着,不能被回收,或者对象的大小直接超过堆内存的对大值。

5.2.2,内存泄漏

指的是对象不再被程序使用,但是GC又回收不了这些对象,就被称为内存泄漏。如一些静态对象,其生命周期比较长,但是这些对象关联了一些只用一次的对象或者一些资源对象,而资源对象没关,如mysql连接等,总而导致出现这个内存泄漏。

5.3,Stop The World

简称STW,指的是在触发这个GC时间之后,会产生程序的停顿,就是会让全部的用户线程暂停,没有任何响应,有点像卡死的感觉。在触发这个STW时,需要保证其工作在一个快照中进行,从而保证数据的一致性,如果在分析过程中出现对象还在不断的动态变化着,则最后的分析结果的准确性很难保证。

在被STW中断的应用程序会在GC之后恢复,然而频繁的中断会让用户感觉到卡顿的情况,让用户的体验不友好,因此在后续的优化中,STW就是重点要关注的对象。并且STW是在后台自动的发起和自动的完成的,会在用户不可见的情况下,强行的把用户正常的线程给全部停掉。因此在开发中也要少用System.gc(),否则也容易触发这个STW。

5.4,引用

当内存空间还足够时,可以保留在内存中,如果内存空间在垃圾收集之后还是很紧张,则可以抛弃这些对象,这些对象就被称为引用。

强引用(StrongReference):指在代码中普遍存在的引用赋值,如通过new一个对象,无论在任何情况下,只要强引用的关系还在,垃圾收集器就永远不会回收掉引用的对象。强引用的对象基本是可触及的,即rootGc是可达的,同时强引用也是内存泄漏的主要原因之一。

StringBuffer sbu = new StringBuffer("zhenghuisheng");

软引用(SoftReference):在系统将要发生内存溢出之前,会将这些回想列入回收范围之中进行第二次回收,如果第一次回收之后(回收GC Root不可达的对象)还没有足够的空间,那么第二次回收就会回收这些对象,第二次回收之后还是内存空间不足,那么就会抛出内存溢出的异常。如一些缓存,就是典型的使用了软引用

//声明一个强引用
Object obj = new Object();
//实例化一个软引用
SoftReference<Object> sf = new SoftReference(obj);
obj = null;

弱引用(WeakReference):只被弱引用关联的对象只能生存到下一次垃圾回收之前,当垃圾回收器工作时,无论空间是否足够,都会被回收。弱引用也可以用来作为缓存使用

//声明一个强引用
Object obj = new Object();
//实例化一个弱引用
WeakReference<Object> sf = new WeakReference(obj);
obj = null;

虚引用(PhantomReference):一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚拟引用来获取一个对象的实例。设置一个虚引用关联的唯一目的是在这个对象被收集器回收时收到一个系统通知

//声明一个强引用
Object obj = new Object();
//引用队列
ReferenceQueue ReferenceQueue = new ReferenceQueue();
//实例化一个虚引用
PhantomReference<Object> sf = new PhantomReference(obj,ReferenceQueue);
obj = null;

总结来说:强引用默认是不回收,软引用是内存不足则回收,弱引用是发现即回收,虚引用是用于对象回收追踪

如若转载,请附上转载链接地址:https://blog.csdn.net/zhenghuishengq/article/details/130261481

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

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

相关文章

一图看懂 xlrd 模块:读写 Excel 文件的数据和格式信息, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 xlrd 模块&#xff1a;读写 Excel 文件的数据和格式信息, 资料整理笔记&#xff08;大全&#xff09; 摘要模块图类关系图模块全展开【xlrd】统计常量intdict 模块26 os27 …

【蓝桥杯省赛真题19】python完数及个数 青少年组蓝桥杯python编程省赛真题解析

目录 python完数及个数 一、题目要求 1、编程实现 2、输入输出 二、解题思路

itop-3568开发板驱动学习笔记(22)设备树(一)设备树基础

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录 设备树简介设备树编译设备树语法设备根节点设备子节点节点名称reg 属性#address-cell 和 #size-cells 属性model 属性status 属性compatible 属性aliases 节点chosen 节点device_type 属性自定义属性 设备树…

使用Docker创建并运行Jenkins详细步骤

文章目录 一、使用Docker搭建Jenkins二、为Jenkins配置执行节点1、进入管理页面2、新建节点3、配置节点信息4、子节点连接master节点5、在子节点机器上运行上面复制下来的命令6、查看子节点是否在线 三、创建一个简单的job1、进入创建页面2、设置job名称3、配置job相关信息4、构…

eBay变现方式有哪些?如何利用好测评自养号?

近年来&#xff0c;越来越多的人选择在eBay开店&#xff0c;甚至很多其他平台的卖家也转型到了eBay。但很多卖家发现&#xff0c;在运营了一段时间后&#xff0c;过了对新账号的流量扶持期&#xff0c;店铺突然出现流量开始下滑的情况&#xff0c;针对这种情况卖家可以采取哪些…

计算机网络(数据链路层)部分习题

1. 通过传统以太网发送中文“华南师范大学计算机学院”&#xff0c;封装成以太网帧&#xff0c;请问该帧的数据字段有效字节是多少&#xff1f;需要填充多少个字节&#xff1f; 答&#xff1a;一个字两个字节&#xff0c;“华南师范大学计算机学院”共11个字&#xff0c;有效字…

Visual Studio容器工具要求在构建,调试或运行容器化项目之前运行Docker

出现此提示&#xff0c;是因为电脑未安装Docker所致&#xff0c;接下来就教大家如何安装Docker。 第一步&#xff1a;下载 地址&#xff1a;Install Docker Desktop on Windows | Docker Documentation 第二步&#xff1a;安装 1、双击Docker Desktop Installer.exe运行安装程…

电子束与材料相互作用Matlab代码

标题 1 题目2 实验原理2.1 蒙特卡洛模拟的基本思想2.2 电子散射的基本概念 3 代码 1 题目 扫描透射电镜(STEM)的基本原理是用极细的扫描电子束透射样品,透射电子直接被具有一定张角的接收器所接收&#xff0c;透射电流的强度直接反应了样品的质量厚度。 对于一定厚度的样品&am…

面试官:一千万的数据,你是怎么查询的?

面试官&#xff1a;一千万的数据&#xff0c;你是怎么查询的&#xff1f; 1 先给结论 对于1千万的数据查询&#xff0c;主要关注分页查询过程中的性能 针对偏移量大导致查询速度慢&#xff1a; 先对查询的字段创建唯一索引 根据业务需求&#xff0c;先定位查询范围&#xff08…

23Java面试专题 八股文面试全套真题(含大厂高频面试真题)

准备篇-01-企业简历筛选规则 准备篇-02-简历注意事项 等写简历的时候看02和04... 准备篇-03-应届生该如何找到合适的练手项目 &#xff01;准备篇-04-Java程序员的面试过程 Redis篇-01-redis开篇 感觉有点难 Redis篇-02-redis使用场景-缓存-缓存穿透 Redis篇-03-redis使用场景-…

一日一题:第十题---并查集(集合合并)and 二叉树遍历

​作者&#xff1a;小妮无语 专栏&#xff1a;一日一题 &#x1f6b6;‍♀️✌️道阻且长&#xff0c;不要放弃✌️&#x1f3c3;‍♀️ 今天来更前几天做的&#xff0c;怕忘记了hh 目录 并查集题目描述(集合合并)代码对路径压缩的解释 二叉树遍历题目描述代码 并查集 ​​​…

【JavaEE】死锁是什么?如何避免死锁(保姆级讲解)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 本篇文章将介绍什么是死锁&#xff0c;死锁的四大必要条件&#xff0c;如何去避免死锁~~~ 目录 一、死锁是什么&#xff1f; 二、关于死锁的情况 2.1 一个线程的情况 2.2 两个线程的情…

javaweb家具购物商城的电商设计与实现

目 录 1 绪论 1 1.1 项目背景 1 1.2 研究意义 1 1.3 本系统概述 2 2系统分析 3 2.1 系统需求分析 3 2.1.1 功能需求 3 2.1.2 性能需求 4 2.2 系统可行性分析 4 2.2.1 技术及开发方法可行性 4 2.2.2 管理可行性 4 2.2.3 经济可行性 5 2.3 业…

CPU的一、二、三级缓存

在Java并发编程中&#xff0c;我们经常会遇到共享变量的读写问题&#xff0c;关于这类问题我们经常会说到原子性、可见性、有序性这三大特性&#xff0c;再进一步会了解到总线和CPU的一、二、三级缓存。关于这三个级别的缓存网上文章介绍比较多&#xff0c;今天我们这篇文章&am…

Django REST Framework(DRF)框架之其他常用API的使用

DRF之其他常用API的使用 限流Throttling限流类设置全局默认限流策略基于类视图限流定义限流频次自定义限流类 过滤Filtering查询集过滤查询参数过滤使用过滤器组件使用过滤器字段过滤字段排序 分页Pagination常用分页类全局与局部的使用自定义分页类 异常处理Exceptions常见异常…

Docder 安装——Windows版

Docder 安装——Windows版 docder 下载地址 https://smartidedl.blob.core.chinacloudapi.cn/docker/20210926/Docker-win.exe 1、使用 PowerShell 启用 Hyper-V 以管理员身份打开 PowerShell 控制台&#xff0c;运行以下命令&#xff1a; Enable-WindowsOptionalFeature -On…

在flowforge中使用模版配置来自定义node-red实例

添加模版设置 在FlowForge中,每个项目都是从模板创建的。模板为项目定义了一组预配置的选项。这包括运行时设置- 比较常见就是 Node-RED settings.js文件中设置的值。 模板还定义了项目可以自定义哪些选项。 本篇文章就来解释一下如何向模板对象中添加新的Node-RED运行时选项…

365天深度学习打卡 YOLOv5白皮书-第Y4周:common.py文件解读

YOLOv5白皮书-第Y4周&#xff1a;common.py文件解读 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 文件位置&#xff1a;./models/common.py 该文件是实现YOLO算法中各个模块的地方&#…

【Cpp】手撕搜索二叉树(KV模型)

文章目录 二叉搜索树的应用搜索二叉树(KV模型)代码:二叉搜索树的性能分析 二叉搜索树的应用 K模型&#xff1a;K模型即只有key作为关键码&#xff0c;结构中只需要存储Key即可&#xff0c;关键码即为需要搜索到的值。 比如&#xff1a;给一个单词word&#xff0c;判断该单词是…

水果FL Studio21最新中文完整版下载更新及内容介绍

简单总结一下&#xff0c;本次小版本更新最重要的内容&#xff0c;我个人认为是对于M1芯片的适配。其余的比如EQ2&#xff0c;3x这些我们很熟悉的插件虽说也有更新&#xff0c;但是估计并没有特别大的改动。我个人的话会先放一段时间&#xff0c;等下次有其他更让我感兴趣的内容…