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

【JVM从入门到实战】(八)垃圾回收(1)

内存泄漏:指的是不再使用的对象在系统中未被回收,内存泄漏的积累可能会导致内存溢出

什么是垃圾回收

Java中为了简化对象的释放,引入了自动的垃圾回收(Garbage Collection简称GC)机制。通过垃
圾回收器来对不再使用的对象完成自动的回收,垃圾回收器主要负责对【】上的内存进行回收。其他
很多现代语言比如C#、Python、Go都拥有自己的垃圾回收器。
在这里插入图片描述
自动垃圾回收 java
自动根据对象是否使用由虚拟机来回收对象
• 优点:降低程序员实现难度、降低对象回收bug的可能性
• 缺点:程序员无法控制内存回收的及时性

手动垃圾回收 C\C++
由程序员编程实现对象的删除
• 优点:回收及时性高,由程序员把控回收的时机
• 缺点:编写不当容易出现悬空指针、重复释放、内存泄漏等问题

Java虚拟机在运行Java程序过程中管理的内存区域,称之为运行时数据区。线程不共享的部分(程序计数器、虚拟机栈、本地方法区),都是伴随着线程的创建而创建,线程的销毁而销毁。而方法的栈帧在执行完方法之后就会自动弹出栈并释放掉对应的内存。
在这里插入图片描述

一、方法区的回收

方法区中能回收的内容主要就是不再使用的类。判定一个类可以被卸载,需要同时满足三个条件:

  1. 此类所有实例对象都已被回收,在堆中不存在任何该类的实例对象以及子类对象。
    在这里插入图片描述

  2. 加载该类的类加载器已被回收
    在这里插入图片描述

  3. 该类对应的 java.lang.Class 对象没有在任何地方被引用
    在这里插入图片描述

开发中此类场景一般很少出现,主要在如OSGi、JSP的热部署等应用场景中。每个jsp文件对应一个唯一的类加载器,当一个jsp文件修改了,就直接卸载这个jsp类加载器。重新创建类加载器,重新加载jsp文件。

手动触发回收
如果需要手动触发垃圾回收,可以调用System.gc()方法。
语法: System.gc()

注意事项:调用System.gc()方法并不一定会立即回收垃圾,仅仅是向Java虚拟机发送一个垃圾回收的请求,具体是否需要执行垃圾回收Java虚拟机会自行判断。

二、堆回收

1. 如何判断堆上的对象可以回收?

Java中的对象是否能被回收,是根据对象是否被引用来决定的。
在这里插入图片描述

如果对象被引用了,说明该对象还在使用,不允许被回收。
图中A的实例对象要回收,有两个引用要去除:

  1. 栈中a1变量到对象的引用 2. B对象到A对象的引用
    a1 = null; b1.a = null;
    在这里插入图片描述

2. 如何判断堆上的对象没有被引用?

常见的有两种方法:引用计数法、可达性分析法

2.1 引用计数法

会为每个对象维护一个引用计数器,当对象被引用时加1,取消引用时减1。

优点:实现简单,C++中的智能指针就采用了引用计数法
缺点:
1.每次引用和取消引用都需要维护计数器,对系统性能会有一定的影响
2.存在循环引用问题,所谓循环引用就是当A引用B,B同时引用A时会出现对象无法回收的问题。
在这里插入图片描述

查看垃圾回收日志,可以使用-verbose:gc参数。
语法: -verbose:gc
在这里插入图片描述

2.2 可达性分析法

Java使用的是可达性分析算法来判断对象是否可以被回收。可达性分析将对象分为两类:垃圾回收的根对象(GC Root)和普通对象,对象与对象之间存在引用关系。
下图中A到B再到C和D,形成了一个引用链,可达性分析算法指的是如果从某个到GC Root对象是可达的,对象就不可被回收。
在这里插入图片描述

哪些对象被称之为GC Root对象呢?
1)线程Thread对象。引用线程栈帧中的方法参数、局部变量等
在这里插入图片描述

2)系统类加载器加载的java.lang.Class对象。引用类中的静态变量
在这里插入图片描述

3)监视器对象,用来保存同步锁synchronized关键字持有的对象。
在这里插入图片描述

4)本地方法调用时使用的全局对象。

查看GC Root
通过arthaseclipse Memory Analyzer (MAT) 工具可以查看GC RootMAT工具是eclipse推出的Java堆内存
检测工具。具体操作步骤如下:
1、使用arthasheapdump命令将堆内存快照保存到本地磁盘中。
2、使用MAT工具打开堆内存快照文件。
3、选择GC Roots功能查看所有的GC Root
在这里插入图片描述

2.3 几种常见的对象引用

可达性算法中描述的对象引用,一般指的是强引用,即是GCRoot对象对普通对象有引用关系,只要这层关系存在,普通对象就不会被回收。
除了强引用之外,Java中还设计了几种其他引用方式:软引用、弱引用、虚引用、终结器引用

1)软引用:
相对于强引用是一种比较弱的引用关系,如果一个对象只有软引用关联到它,当程序内存不足时,就会将软引用中的数据进行回收。在JDK 1.2版之后提供了SoftReference类来实现软引用,软引用常用于缓存中
在这里插入图片描述

软引用的执行过程如下:
1 将对象使用软引用包装起来,new SoftReference<对象类型>(对象)
在这里插入图片描述

2 内存不足时,虚拟机尝试进行垃圾回收。
3 如果垃圾回收仍不能解决内存不足的问题,回收软引用中的对象。
4 如果依然内存不足,抛出OutOfMemory异常。

软引用中的对象如果在内存不足时回收,SoftReference对象本身也需要被回收。如何知道哪些SoftReference对象需要回收呢?SoftReference提供了一套队列机制:
1 软引用创建时,通过构造器传入引用队列
2 在软引用中包含的对象被回收时,该软引用对象会被放入引用队列
3 通过代码遍历引用队列,将SoftReference的强引用删除

2)弱引用:
整体机制和软引用基本一致,区别在于弱引用包含的对象在垃圾回收时,不管内存够不够都会直接被回收。在JDK 1.2版之后提供了WeakReference类来实现弱引用,弱引用主要在ThreadLocal中使用。弱引用对象本身也可以使用引用队列进行回收。
在这里插入图片描述

3)虚引用和终结器引用

  • 这两种引用在常规开发中不会使用到,仅了解。
  • 虚引用也叫幽灵引用/幻影引用,不能通过虚引用对象获取到包含的对象。虚引用唯一的用途是当对象被垃圾回收器回收时可以接收到对应的通知。Java中使用PhantomReference实现了虚引用,直接内存中为了及时知道直接内存对象不再使用,从而回收内存,使用了虚引用来实现。
  • 终结器引用指的是在对象需要被回收时,终结器引用会关联对象并放置在Finalizer类中的引用队列中,在稍后由一条由FinalizerThread 线程从队列中获取对象,然后执行对象的finalize方法,在对象第二次被回收时,该对象才真正的被回收。在这个过程中可以在finalize方法中再将自身对象使用强引用关联上,但是不建议这样做。

三、垃圾回收算法

垃圾回收要做的有两件事:
1)找到内存中存活的对象
2)释放不再存活对象的内存,使得程序能再次利用这部分空间

四种算法:标记-清除算法、复制算法、标记-整理算法、分代GC

垃圾回收算法的评价标准

Java垃圾回收过程会通过单独的GC线程来完成,但是不管使用哪一种GC算法,都会有部分阶段需要停止所有的用户线程。这个过程被称之为Stop The World简称STW,如果STW时间过长则会影响用户的使用。

判断GC算法是否优秀,可以从三个方面来考虑:
1)吞吐量:指的是 CPU 用于执行用户代码的时间CPU 总执行时间的比值
吞吐量 = 执行用户代码时间 /(执行用户代码时间 + GC时间)。吞吐量数值越高,垃圾回收的效率就越高。比如:虚拟机总共运行了 100 分钟,其中GC花掉 1 分钟,那么吞吐量就是 99%
2)最大暂停时间:最大暂停时间指的是所有在垃圾回收过程中的STW时间最大值。最大暂停时间越短,用户使用系统时受到的影响就越短。

比如如下的图中,黄色部分的STW就是最大暂停时间,显而易见上面的图比下面的图拥有更少的最大暂停时间。
在这里插入图片描述

3)堆使用效率:不同垃圾回收算法,对堆内存的使用方式是不同的。比如标记清除算法,可以使用完整的堆内存。而复制算法会将堆内存一分为二,每次只能使用一半内存。从堆使用效率上来说,标记清除算法要优于复制算法。

上述三种评价标准:堆使用效率、吞吐量,以及最大暂停时间不可兼得。

一般来说,堆内存越大,最大暂停时间就越长。想要减少最大暂停时间,就会降低吞吐量。不同的垃圾回收算法,适用于不同的场景

1. 标记清除算法

标记清除算法的核心思想分为两个阶段
1)标记阶段,将所有存活的对象进行标记。Java中使用可达性分析算法,从GC Root开始通过引用链遍历出所有存活对象。
2)清除阶段,从内存中删除没有被标记也就是非存活对象

优点:实现简单,只需要在第一阶段给每个对象维护标志位,第二阶段删除对象即可。

缺点:1)碎片化问题:由于内存是连续的,所以在对象被删除之后,内存中会出现很多细小的可用内存单元。如果我们需要的是一个比较大的空间,很有可能这些内存单元的大小过小无法进行分配。
在这里插入图片描述

2)分配速度慢:由于内存碎片的存在,需要维护一个空闲链表,极有可能发生每次需要遍历到链表的最后才能获得合适的内存空间。
在这里插入图片描述

2. 复制算法

复制算法的核心思想是:
1)准备两块空间From空间和To空间,每次在对象分配阶段,只能使用其中一块空间(From空间)。
2)在垃圾回收GC阶段,将From中存活对象复制到To空间。
3)将两块空间的FromTo名字互换。
在这里插入图片描述

完整的复制算法的例子:
1.将堆内存分割成两块From空间 To空间,对象分配阶段,创建对象。
2.GC阶段开始,将GC Root搬运到To空间
3.将GC Root关联的对象,搬运到To空间
4.清理From空间,并把名称互换

优点:
1)吞吐量高:复制算法只需要遍历一次存活对象复制到To空间即可,比标记-整理算法少了一次遍历的过程,因而性能较好,但是不如标记-清除算法,因为标记清除算法不需要进行对象的移动
2)不会发生碎片化:复制算法在复制之后就会将对象按顺序放入To空间中,所以对象以外的区域都是可用空间,不存在碎片化内存空间。

缺点:内存使用效率低,每次只能让一半的内存空间来为创建对象使用

3. 标记整理算法

标记整理算法也叫标记压缩算法,是对标记清理算法中容易产生内存碎片问题的一种解决方案。

核心思想分为两个阶段
1)标记阶段,将所有存活的对象进行标记。Java中使用可达性分析算法,从GC Root开始通过引用链遍历出所有存活对象。
2)整理阶段,将存活对象移动到堆的一端。清理掉存活对象的内存空间。
在这里插入图片描述

优点:
1)整个堆内存都可以使用,不会像复制算法只能使用半个堆内存
2)不会发生碎片化,在整理阶段可以将对象往内存的一侧进行移动,剩下的空间都是可以分配对象的有效空间

缺点:整理阶段的效率不高。整理算法有很多种,比如Lisp2整理算法需要对整个堆中的对象搜索3次,整体性能不佳。可以通过Two Finger表格算法ImmixGC等高效的整理算法优化此阶段的性能

4. 分代垃圾回收算法

在这里插入图片描述
分代垃圾回收将整个内存区域划分为年轻代和老年代:年轻代(新生代) Young区存放存活时间比较短的对象,Old区老年代存放存活时间比较长的对象.

1)分代回收时,创建出来的对象,首先会被放入Eden伊甸园区。随着对象在Eden区越来越多,如果Eden区满,新创建的对象已经无法放入,就会触发年轻代的GC,称为Minor GC或者Young GCMinor GC会把eden区和From区(S0)中需要回收的对象回收,把没有回收的对象放入To区(S1)。
在这里插入图片描述

2)接下来,S0会变成To区,S1变成From区。当eden区满时再往里放入对象,依然会发生Minor GC。此时会回收eden区和S1(from)中的对象,并把edenfrom区中剩余的对象放入S0。每次Minor GC中都会为对象记录他的年龄,初始值为0,每次GC完加1。
在这里插入图片描述

3)如果Minor GC后对象的年龄达到阈值(最大15,默认值和垃圾回收器有关),对象就会被晋升至老年代。当老年代中空间不足,无法放入新的对象时,先尝试minor gc如果还是不足,就会触发Full GCFull GC会对整个堆进行垃圾回收。如果Full GC依然无法回收掉老年代的对象,那么当对象继续放入老年代时,就会抛出Out Of Memory异常。
在这里插入图片描述

下图中的程序为什么会出现OutOfMemory?
在这里插入图片描述
从上图可以看到,Full GC无法回收掉老年代的对象,那么当对象继续放入老年代时,就会抛出Out Of Memory异常。

arthas查看分代之后的内存情况
JDK8中,添加-XX:+UseSerialGC参数使用分代回收的垃圾回收器,运行程序。
arthas中使用memory命令查看内存,显示出三个区域的内存情况。 图2
在这里插入图片描述

调整内存区域的大小:通过添加jvm启动参数修改各个区域大小和比例。注意加上-XX:+UseSerialGC
在这里插入图片描述

为什么分代GC算法要把堆分成年轻代和老年代

  • 系统中的大部分对象,都是创建出来之后很快就不再使用可以被回收,比如用户获取订单数据,订单数据返回给用户之后就可以释放了。
  • 老年代中会存放长期存活的对象,比如Spring的大部分bean对象,在程序启动之后就不会被回收了。
  • 在虚拟机的默认设置中,新生代大小要远小于老年代的大小。
    在这里插入图片描述
    答:分代GC算法将堆分成年轻代和老年代主要原因有:
    1.可以通过调整年轻代和老年代的比例来适应不同类型的应用程序,提高内存的利用率和性能。
    2)新生代和老年代使用不同的垃圾回收算法,新生代一般选择“复制算法”,老年代可以选择“标记-清除”和“标记-整理”算法,由程序员来选择灵活度较高。
    3)分代的设计中允许只回收新生代(minor gc),如果能满足对象分配的要求就不需要对整个堆进行回收(full gc),STW时间就会减少。
    在这里插入图片描述

相关文章:

【JVM从入门到实战】(八)垃圾回收(1)

内存泄漏&#xff1a;指的是不再使用的对象在系统中未被回收&#xff0c;内存泄漏的积累可能会导致内存溢出 什么是垃圾回收 Java中为了简化对象的释放&#xff0c;引入了自动的垃圾回收&#xff08;Garbage Collection简称GC&#xff09;机制。通过垃 圾回收器来对不再使用的…...

LeeCode前端算法基础100题(12)-删除有序数组中的重复项

一、问题详情: 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题…...

MATLAB图解傅里叶变换(初学者也可以理解)

1、概述 相信很多人对于傅里叶变换可能觉得比较复杂和有点难懂&#xff0c;其实不难&#xff0c;它只是一种积分变换。 傅里叶变换&#xff0c;表示能将满足一定条件的某个函数表示成三角函数&#xff08;正弦和/或余弦函数&#xff09;或者它们的积分的线性组合。也就是说&qu…...

uni-app 用于开发H5项目展示饼图,使用ucharts 饼图示例

先下载ucharts H5示例源码&#xff1a; uCharts: 高性能跨平台图表库&#xff0c;支持H5、APP、小程序&#xff08;微信小程序、支付宝小程序、钉钉小程序、百度小程序、头条小程序、QQ小程序、快手小程序、360小程序&#xff09;、Vue、Taro等更多支持canvas的框架平台&#…...

回归预测 | MATLAB实现SABO-LSTM基于减法平均优化器优化长短期记忆神经网络的多输入单输出数据回归预测模型 (多指标,多图)

回归预测 | MATLAB实现SABO-LSTM基于减法平均优化器优化长短期记忆神经网络的多输入单输出数据回归预测模型 &#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现SABO-LSTM基于减法平均优化器优化长短期记忆神经网络的多输入单输出数据回归预测模型 &a…...

JDK bug:ciObjectFactory::create_new_metadata

文章目录 1、问题2.详细日志3.JDK&#xff1a;bug最终bug链接&#xff1a; 京东遇到过类似bug各位大佬如果有更详细的解答可以留言。 1、问题 Problematic frame: V [libjvm.so0x438067] ciObjectFactory::create_new_metadata(Metadata*)0x327 关键字还是ciObjectFactory::cr…...

Flink系列之:Over聚合

Flink系列之&#xff1a;Over聚合 一、Over聚合二、ORDER BY三、PARTITION BY四、范围&#xff08;RANGE&#xff09;定义五、RANGE 间隔六、ROW 间隔 适用于流、批 一、Over聚合 OVER 聚合通过排序后的范围数据为每行输入计算出聚合值。和 GROUP BY 聚合不同&#xff0c; OV…...

Java开发工具积累(符合阿里巴巴手册规范)

文章目录 一、命名规约二、代码格式三、集合篇1. 栈、队列、双端队列2. List的升序倒序3. Map的升序降序4. 二维数组排序5. 集合之间的转换6. Map键值对遍历7. 重写equal与hashCode8. ArrayList的subList9. keySet&#xff08;&#xff09;/values&#xff08;&#xff09;/ent…...

SiLM5350MDBCA-DG车规级隔离驱动芯片,我们能为汽车智能提供什么?

SiLM5350MDBCA-DG是一款适用于IGBT、MOSFET的单通道 隔离门极驱动器&#xff0c;具有10A拉电流和10A灌电流驱动能 力。提供内部钳位功能&#xff0c;可单独控制 上升时间和下降时间。 在 SOP8 封 装 中 具 有 3000VRMS 隔 离 耐 压 &#xff08; 符 合 UL1577&#xff09;。 与…...

【开题报告】基于SpringBoot的企业财务管理系统的设计与实现

1.研究背景 随着全球经济的发展和市场竞争的加剧&#xff0c;企业财务管理变得越来越重要。企业需要一个高效、精确、安全的财务管理系统来管理企业的财务事务&#xff0c;提供准确的财务数据支持决策制定。传统的手工财务管理方式已经无法满足企业的需求&#xff0c;因此&…...

【C盘清理】Jetbrains全家桶(PyCharm、Clion……)更改 IDE 特定文件(配置、缓存、插件、日志等)存储位置

文章目录 一、官网说明二、更改 IDE 目录的位置1. 转到“帮助”|“编辑自定义属性”2. 各文件位置3. 以PyCharm系统目录为例4. 修改idea.properties 三、清理旧的 IDE 目录 一、官网说明 IDE 使用的目录官网说明 二、更改 IDE 目录的位置 默认情况下&#xff0c;PyCharm 将每…...

nginx部署vue项目

nginx部署vue 解决nginx中vue项目刷新报404问题解决nginx转发后端服务隐藏部分url访问url路径/prod-api/api经过nginx反向代理后&#xff0c;到达后端服务的实际url地址为/api。 解决nginx中vue项目刷新报404问题 location / { …...

Relocations for this machine are not implemented,IDA版本过低导致生成汇编代码失败

目录 1、问题描述 2、安卓app发生崩溃&#xff0c;需要查看汇编代码上下文去辅助分析 3、使用IDA打开.so动态库文件&#xff0c;提示Relocations for this machine are not implemented 4、IDA版本较老&#xff0c;不支持ARM64的指令集&#xff0c;使用7.0版本就可以了 5、…...

[ CTF ]【天格】战队WriteUp-第七届“强网杯”全国安全挑战赛

第七届“强网杯”全国安全挑战赛 2023.12.16~2023.12.17 文章目录 【Misc】Pyjail ! Its myFILTER !!!easyfuzz谍影重重2.0签到Pyjail ! Its myRevenge !!!server_8F6C72124774022B.py 问卷调查 【Reverse】ezre 【Web】happygame 【强网先锋】石头剪刀布TrieSpeedUpezreez_fmt…...

Android13音频录制适配

Android13音频录制适配 前言&#xff1a; 之前写过一篇音频录制的文章&#xff0c;当时是在Android10以下的手机可以成功录制和播放&#xff0c;但是Android10及以上手机提示创建文件失败&#xff0c;最近做过Android13的适配&#xff0c;索性一起把之前的录音也适配了&#…...

【Python】—— 如果使用matplotlib做数据可视化

matplotlib做数据可视化 相关知识掌握matplotlib的基本使用方法1. 折线图2. 散点图3. 柱状图4. 饼图5. 直方图6. 等高线图7. 图形定制 掌握数据处理的基本方法1. 数据筛选2. 缺失值处理3. 异常值处理 理解数据可视化的原则和方法1. 选择合适的图表类型2. 避免数据混淆3. 突出重…...

【MyBatis-Plus】多数据源分页配置(低版本暂时就支持一种(可选),高版本多支持)

【转载】一、Mybatis Plus 3.4 版本之后分页插件的变化 1、地址 Mybatis Plus 3.4版本之后分页插件的变化 2、内容 1、MybatisPlusInterceptor 从 Mybatis Plus 3.4.0 版本开始&#xff0c;不再使用旧版本的 PaginationInterceptor&#xff0c;而是使用 MybatisPlusInterce…...

Linux 特殊符号

目录 1. # 注释 2. &#xff1b;命令分隔符 3. .. 上级目录 4. . 当前目录 5. " " 换行&#xff0c;解析变量 6. 换行&#xff0c;不解析变量 7. \ 和 / 8. &#xff01;历史命令调用&#xff0c;取反 9. * 通配符 10. $ 调用变量 11. | 管道 12. || …...

TDengine 签约中船九院,助力航运业智能化转型升级

在大数据时代背景下&#xff0c;船舶智能化已经成为船舶制造与航运领域发展的必然趋势。智能船舶作为《中国制造 2025》中明确重点发展的领域&#xff0c;代表了船舶未来的方向&#xff0c;对于航运业的转型升级至关重要。其中&#xff0c;大数据的处理和运用成为船舶智能化转型…...

upload-labs笔记

简介 upload-labs是一个使用php语言编写的&#xff0c;专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共21关&#xff0c;每一关都包含着不同上传方式。 文件上传漏洞是指&#xff1a; Web 服务器允许用户将文件上传至其…...

Android Studio好用的插件推荐

目录 一、插件推荐 二、如何下载 1.点击File—>Settings ​2.点击Plugins然后进行搜索下载 三、Android Studio 模板 一、插件推荐 这个插件可以为您自动生成Parcelable代码。Parcelable是一种用于在Android组件之间传递自定义对象的机制&#xff0c;但手动编写Parcela…...

第三十九章 其他特殊主题 - 映射 IRIS ID 以供导出

文章目录 第三十九章 其他特殊主题 - 映射 IRIS ID 以供导出控制导出时的命名空间前缀XMLPREFIX 第三十九章 其他特殊主题 - 映射 IRIS ID 以供导出 当在顶层映射 IRIS 对象&#xff08;而不是作为另一个对象的属性&#xff09;时&#xff0c;其内部 ID、OID 和全局唯一 ID 不…...

文件操作(下)

标题的顺序是接着之前写的&#xff0c;希望这篇博客对你有帮助 七. 随机读写函数 实际上&#xff0c;无论是读还是写&#xff0c;在一次调用顺序读写函数&#xff0c;文件指针会移到已经读过或者写过的下一个位置&#xff0c;从那个位置开始下一次读和写&#xff08;在文件没有…...

面试必问-vue3中ref与这个reactive的区别

ref和reactive是Vue 3中两种不同的响应式数据处理方式。 ref&#xff1a;ref函数可以将普通的Javascript值转换为一个响应式引用。它返回一个包含.value属性的对象&#xff0c;可以通过读取或修改.value来操作引用的值。当引用的值发生变化时&#xff0c;Vue会自动追踪依赖并更…...

网络(九)三层路由、DHCP以及VRRP协议介绍

目录 一、三层路由 1. 定义 2. 交换原理 3. 操作演示 3.1 图示 3.2 LSW1新建vlan10、20、30&#xff0c;分别对应123接口均为access类型&#xff0c;接口4为trunkl类型&#xff0c;允许所有vlan通过 3.3 LSW2新建vlan10、20、30&#xff0c;配置接口1为trunk类型&…...

深度学习 Day19——P8YOLOv5-C3模块实现

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 文章目录 前言1 我的环境2 代码实现与执行结果2.1 前期准备2.1.1 引入库2.1.2 设置GPU&#xff08;如果设备上支持GPU就使用GPU,否则使用C…...

轻量封装WebGPU渲染系统示例<51>- 视差贴图(Parallax Map)(源码)

视差纹理是一种片段着色阶段增强材质表面凹凸细节的技术。 这里在WebGPU的实时渲染材质管线中实现了视差贴图计算&#xff0c;以便增强相关的纹理细节表现力。 当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/Para…...

YOLOv8改进 | 2023主干篇 | 华为最新VanillaNet主干替换Backbone实现大幅度长点

一、本文介绍 本文给大家来的改进机制是华为最新VanillaNet网络&#xff0c;其是今年最新推出的主干网络&#xff0c;VanillaNet是一种注重极简主义和效率的神经网络架构。它的设计简单&#xff0c;层数较少&#xff0c;避免了像深度架构和自注意力这样的复杂操作(需要注意的是…...

Leetcode 376 摆动序列

题意理解&#xff1a; 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 如果是摆动序列&#xff0c;前后差值呈正负交替出现 为保证摆动序列尽可能的长&#xff0c;我们可以尽可能的保留峰值&#xff0c;&#xff0c;删除上下坡的中间值&…...

51单片机控制1602LCD显示屏输出自定义字符二

51单片机控制1602LCD显示屏输出自定义字符二 1.概述 1602LCD除了内置的字符外还提供自定义字符功能&#xff0c;当内置的字符中没有我们想要输出的字符时&#xff0c;我们就可以自己创造字符让他显示&#xff0c;下面介绍1602如何创建自定义字符。 2.1602LCD创建字符原理 自…...