JVM垃圾回收与双亲委派模型

news2024/9/21 16:47:44

观前提示:本篇博客演示使用的 IDEA 版本为2021.3.3版本,使用的是Java8(又名jdk1.8)

前端使用VSCode(Visual Studio Code1.78.2)

电脑使用的操作系统版本为 Windows 10


目录

1. 什么是 JVM

2. jvm 发展史

2.1 Sun Classic VM

2.2 Exact VM

2.3 HotSpot VM

2.4 JRockit

2.5 J9 JVM

2.6 Taobao JVM(国产研发)

3. JVM 内存区域划分

3.1 堆

3.2 Metaspace (元数据区)

3.3 给一段代码, 问某个变量是在那个区域上?

4. JVM 类加载

4.1 类加载过程

5. 双亲委派模型

5.1 上述类加载器如何配合工作?

5.2 为什么会有上述这种顺序?

5.3 为什么叫双亲委派模型 

6. JVM 垃圾回收机制

6.1 GC 实际工作过程

6.1.1 找到垃圾/判断垃圾

6.1.1.1 引用计数(python/php)

6.1.1.2 可达性分析(java)

6.2 JVM 如何清理垃圾

6.2.1 标记清除

6.2.2 复制算法

6.2.3 标记整理

6.2.4 分代回收


1. 什么是 JVM

JVM(Java Virtual Machine)是指Java虚拟机,它是 Java 语言的核心和关键技术之一。JVM 是一个软件平台,用于在不同计算机体系结构和操作系统上运行 Java 字节码。Java 开发人员使用 Java 编写的程序通过编译器生成字节码,然后 JVM 将字节码解释并转换成可以在特定硬件和操作系统上运行的本地机器代码。这种可移植性是 Java 的一个重要特点,使 Java 程序可以跨平台运行。JVM 还有垃圾回收、内存管理等重要功能,可以帮助 Java 开发者更加高效地创建稳定、可靠的应用程序。

2. jvm 发展史

2.1 Sun Classic VM

早在1996年 Java1.0 版本的时候,Sun 公司发不了一款名为 Sun Classic vm 的 java 虚拟机,它同时也是世界上第一款商业 java 虚拟机,jdk1.4 时完全被淘汰。
这款虚拟机内部只提供解释器。如果使用 JIT 编译器,就需要进行外挂。但是一旦使用了JIT编译器,JIT就会接管虚拟机的执行系统。解释器就不再工作。解释器和编译器不能配合工作。现在 Hotspot 内置了此虚拟机
 

2.2 Exact VM

为了解决上一个虚拟机问题,jdk1.2时,sun提供了此虚拟机。
Exact 具备现代高性能虚拟机的雏形,包含了一下功能:
1. 热点探测(将热点代码编译为字节码加速程序执行);
2. 编译器与解析器混合工作模式。
只在Solaris平台短暂使用,其他平台上还是 classic vm英雄气短,终被Hotspot虚拟机替换。
 

2.3 HotSpot VM

HotSpot 历史
1. 最初由一家名为 “Longview Technologies” 的小公司设计;
2. 1997年,此公司被 Sun 收购;2009年,Sun 公司被甲骨文收购。
3. JDK1.3 时,HotSpot VM 成为默认虚拟机
目前 HotSpot 占用绝对的市场地位,称霸武林。
不管是现在仍在广泛使用 JDK6,还是使用比较多的 JDK8 中,默认的虚拟机都是 HotSpot ;Sun/Oracle JDK和OpenJDK 的默认虚拟机。从服务器、桌面到移动端、嵌入式都有应用。名称中的HotSpot指的就是它的热点代码探测技术。它能通过计数器找到最具编译价值的代码,触发即时编译(JIT)或栈替换;通过编译器与解释器协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡。
 

2.4 JRockit

它可以不太关注程序的启动速度,因此JRockit内部不包含解析器实现,全部代码都靠即时编译器编译后执行;大量的行业基准测试显示,JRockit JVM 是世界上最快的 JVM。
使用 JRockit 产品,客户已经体验到了显著的性能提高(一些超过了70%)和硬件成本的减少(达50%);优势:全面的Java运行时解决方案组合。 JRockit 面向延迟敏感型应用的解决方案 JRockit Real Time 提供以毫秒或微秒级的JVM响应时间,适合财务、军事指挥、电信网络的需要;MissionControl 服务套件,它是一组以极低的开销来监控、管理和分析生产环境中的应用程序的工具;2008,BEA 被 Oracle 收购。Oracle 表达了整合两大优秀虚拟机的工作,大致在 JDK8 中完成。整合的方式是在 HotSpot 的基础上,移植 JRockit 的优秀特性。

2.5 J9 JVM

全称:IBM Technology for Java Virtual Machine,简称IT4J,内部代号:J9。
市场定位于HotSpot接近,服务器端、桌面应用、嵌入式等多用途JVM,广泛用于IBM的各种Java产品。目前,有影响力的三大商用虚拟机之一,也号称是世界上最快的Java虚拟机(在IBM自己的产品上稳定);2017年左右,IBM发布了开源 J9 VM,命名 OpenJ9,交给 Eclipse 基金会管理,也称为 Eclipse OpenJ9。
 

2.6 Taobao JVM(国产研发)

由 AliJVM 团队发布。阿里,国内使用Java最强大的公司,覆盖云计算、金融、物流、电商等众多领域,需要解决高并发、高可用、分布式的复合问题。有大量的开源产品。
基于OpenJDK 开发了自己的定制版本AlibabaJDK,简称AJDK。是整个阿里JAVA体系的基石;基于OpenJDK HotSpot JVM发布的国内第一个优化、深度定制且开源的高性能服务器版Java虚拟机,它具有以下特点(了解):
1. 创新的GCIH(GC invisible heap)技术实现了off-heap,即将生命周期较长的Java对象从heap中移到heap之外,并且GC不能管理GCIH内部的Java对象,以此达到降低GC的回收评率和提升GC的回收效率的目的。
2. GCIH中的对象还能够在多个Java虚拟机进程中实现共享。
3. 使用crc32指令实现JVM intrinsic降低JNI的调用开销;
4. PMU hardware的Java profiling tool和诊断协助功能;
5. 针对大数据场景的ZenGC。
taobao JVM应用在阿里产品上性能高,硬件严重依赖intel的cpu,损失了兼容性,但提高了性能,目前已经在淘宝、天猫上线,把Oracle官方JVM版本全部替换了。

3. JVM 内存区域划分

JVM 启动的时候,会向操作系统申请一片内存区域, JVM 根据需要, 把整个空间分成几个部分, 每个部分各司其职

Native Method Stacks (本地方法栈): 表示 JVM 内部的 C++ 代码, 就是调用 native 方法(JVM 内部的方法)准备的栈空间

Program Counter Register (程序计数器): 记录当前线程执行到那个指令(很小的一块存一个地址)每个线程都有一份

Java Stacks (虚拟机栈): 给 Java 代码使用的栈

栈帧-1(方法A), 栈帧-2(方法B), 栈帧-3(方法C) ......: 每个线程一个栈帧, jconsole 可以通过查看 Java 进程内部的情况,从而看到所有的线程, 点击线程就能看到该线程调用栈的情况

注意: stack 在数据结构中虽然也是栈的意思, 但他是 "先进后出", 和 JVM 中的栈不是一个东西.

JVM 的栈,是一个特定空间, 对于 JVM 虚拟机栈, 这里存储的是 方法 之间的 调用关系

整个栈空间内部, 可以认为是包含了很多元素(每个元素表示一个方法)把这里的每个元素, 称为是一个"栈帧", 这一个栈帧里,会包含这个方法的 入口地址, 方法的参数是什么, 返回地址是什么, 局部变量

对于 本地方法栈, 存储的是 native 方法之间的调用关系

由于是 函数 调用, 因此也有"先进后出" 的特点, 因此此处的栈,也是先进后出 

3.1 堆

堆是整个 JVM 空间最大的区域, new 出来的对象都是在堆上面, 类的成员变量也在堆上面,

堆是一个进程只有一份; 栈是每个线程有一份, 一个进程有 N 个

堆是多个线程共用一个; 栈是每个线程都有自己的

3.2 Metaspace (元数据区)

kiass 类元信息: 类对象, 常量池, 静态成员 就是存储在这里

Java 7以及之前叫做方法区, Java 8之后改名为 元数据区

3.3 给一段代码, 问某个变量是在那个区域上?

原则:

1. 局部变量: 栈

2.普通成员变量: 堆

3. 静态普通成员变量: 方法区/元数据区          

4. JVM 类加载

4.1 类加载过程

类加载就是 .class 文件, 从文件(硬盘)被加载到内存中(元数据区)这样的过程

加载: 把 .class 文件找到(找的过程), 打开文件, 读文件, 把文件内容读到内存中区

验证: 检查 .class 文件格式是否符合需求, .class 文件是一个二进制文件, 这里的格式是有严格说明的, 官方提供了 JVM 虚拟机规范, 规范文档上面详细描述了 .class 的格式

准备: 给类对象分配内存空间(现在元数据区占个位置), 也会使静态成员被设置成 0 值

解析: 初始化字符串常量, 把符号引用转为直接引用

初始化: 调用构造方法, 进行成员初始化, 执行代码块, 静态代码块, 加载父类...

一个类什么时候才被加载呢?

不是 Java 程序一运行就把所有的类加载了, 而是真正用到才加载(懒汉模式)

以下这三种用到了才加载, 一旦加载过, 后续使用就不必重复加载了

1. 构造 类 的实例

2. 调用这个类的 静态方法 / 使用静态属性

3. 加载子类, 就会先加载其父类

其中, 解析里的字符串常量, 需要有一块内存空间, 存这个字符的实际内容, 还得有一个引用, 来保存这个内存空间的起始地址

在类加载之前, 字符串常量, 此时是处在 .class 文件中, 此时这个"引用"记录的并非是字符串常量的真正的地址, 而是他在文件中"偏移量"这个东西(或者是个占位符)类加载之后, 才真正把这个字符串常量给放到内存中, 此时才有"内存地址", 这个引用才能被真正赋值成指定内存地址

举个例子:

学校组织讲座的时候,在进入报告厅之前只知道我的前面是A后面是B,不知道具体坐在那里(符号引用)

此时我只知道自己的相对位置

进入报告厅以后, 大家开始坐下, 当我真正的坐下之后, 我才知道自己的真实的位置(直接引用)

再来看"验证"里面说的官方 JVM 虚拟机规范

Java SE 官方文档

往下拉,找到 Java SE 8

 点击 Java SE 8 Edition 的 HTML

找到 4 点击 4.1

就能看到这个 

 

5. 双亲委派模型

加载: 把 .class 文件找到, 读取文件内容. 而双亲委派模型描述的就是加载, 找 .class 文件 的基本过程

 

上述三个类, 存在"父子关系"(不是父类子类, 相当于每个 class loader 有一个 parent 属性, 指向自己的 类加载器)

5.1 上述类加载器如何配合工作?


首先加载一个类的时候,是先从 Application ClassLoader 开始, 但是 Application ClassLoader 会把加载任务交给父类加载器让父类加载器去进行
于是 Extension ClassLoader 要去加载但是也不是真加载而是再委托给自己的父类加载器
Bootstrap ClassLoader 要去加载,也是想委托给自己的父类加载器,结果发现自己的父类加载器是 null
(没有父类加载器或者父类加载器加载完了,没找着类,才由自己进行加载)
此时 Bootstrap ClassLoader 就会搜索自己负责的标准库目录的相关的类,如果找到就加载,如果没找到就继续由子类加载器进行加载
Extension ClassLoader 真正搜索扩展库相关的目录,如果找到就加载,如果没找到就由子类加载器进行加载
Application ClassLoader 真正搜索用户项目相关的目录,如果找到就加载,没找到由子类加载器进行加载(由于当前没有子类了,就只能抛出 "类找不到" 这样的异常)

5.2 为什么会有上述这种顺序?

上述这套顺序其实是出自于JVM 实现代码的逻辑,这段代码大概是类似于"递归"的方式写的。
其实从最上面这里直接开始也不是不行,但是 JVM 代码当前是按照这种类似递归的方式来实现的,就导致了从下到上又从上到下的过程。
这个顺序最主要的目的就是为了保证 Bootstrap 能够先加载 Application 能够后加载,这样就可以避免因为用户创建了一些奇怪的类引起不必要的bug
假设用户在自己的代码中写了个 Java.lang.String 这个类
按照上述加载流程,此时 JVM 加载的还是标准库的类,不会加载到用户自己写的这个类,这样就能保证即使出现上述问题也不会让 JVM 已有代码混乱,最多是用户自己写的类不生效罢了
另一方面,类加载器其实是可以用户自定义的,上述三个类加载器是 JVM 自带的,用户自定义的类加载器也可以加入到上述流程中,就可以和现有的加载配合使用了

5.3 为什么叫双亲委派模型 

双亲委派模型没有双亲, 只有父亲, 因为他是机翻, 他更应该叫做 "单亲委派模型"或者"父亲委派模型"

parent 双亲之一

 

6. JVM 垃圾回收机制

为什么要有垃圾回收?回收的垃圾指的是什么?回收的垃圾指的是不再使用的内存,而垃圾回收就是把不用的内存帮我们自动释放掉。
C 和 C++ 中,动态内存申请是在堆上申请一块内存空间当不用这块内存空间的时候,需要手动进行释放。
如果不手动进行释放这块内存的空间就会持续存在,一直存在到进程结束。
堆上的内存生命周期比较长,不像栈,栈的空间会随着方法执行结束,栈帧销毁而自动释放。堆,则默认不能自动释放。
这就会导致一个非常严重的问题,内存泄露。
如果内存一直占着不用又不释放,就会导致剩余空间越来越少,进一步导致后续的内存申请操作失败,尤其是服务器特别害怕这个,因为服务器是 7*24 小时运营。
为了解决内存泄露,大佬们想了一些办法,GC 是其中最主流的一种方式,
JAVA, Python, PHP,GO,JS 等大部分主流语言都是使用 GC 来解决上述问题的。


那么 C 和 C++ 为什么不使用 GC 呢?或者整一个类似于 GC 的东西?

C++ 要搞肯定也能搞出来但是 GC 必然是有好的一面,也有坏的一面
GC 好处:非常省心,让程序员写代码简单点,不容易出错
GC 坏处:需要消耗额外的系统资源,也有额外的性能开销

Gc的坏处就不符合在 C++ 的初心(追求性能的极致)
另外 GC 还有一个比较关键的问题,STW 问题
如果有时候内存中的垃圾已经很多了,此时触发一次 GC 操作开销可能非常大, 大到可能就把系统资源吃了很多,另一方面 GC 回收垃圾的时候可能会涉及到一些锁操作,导致业务代码无法正常执行,这样的卡顿,极端情况下可能是出现几十毫秒甚至上百毫秒

同样不符合 C++ 的初心

6.1 GC 实际工作过程

JVM 里面有好多内存区域

而 GC 正是针对 堆 进行释放的, GC 是以 "对象" 为基本单位, 进行回收(不是字节)

GC 回收的是整个对象都不在使用的情况, 而一部分使用, 一部分不使用的对象, 暂时先不回收

(一个对象里面有很多属性, 可能是其中十个属性后面要用,十个属性后面再也不用)

因此, 要回收就回收整个对象, 而不会"回收整个对象". 这样设定, 简单

 

6.1.1 找到垃圾/判断垃圾

如何确定这个内存是不是垃圾,关键思路就是有没有“引用“指向他
JAVA中使用对象只有这一条路,通过"引用"来使用,如果一个对象有引用指向,他就可能被使用到。如果一个对象没有引用指向就不会再被使用。

具体如何知道对象是否有引用指向呢?两种典型实现:

1. 引用计数(Python/PHP)

2.可达性分析(Java)

6.1.1.1 引用计数(python/php)

给每个对象分配一个计数器(整数),每次创建一个引用指向该对象计数器就+1,每次该引用被销毁了,计数器就-1。

 

缺陷:
这个办法简单有效但是java并没有使用
1. 内存空间浪费的多(利用率低)
每个对象都要分配一个计数器,如果按四个字节算,代码中的对象非常少,无所谓,如果对象特别多了,占用的额外空间就会很多,尤其是每个对象都比较小的情况。
一个对象体积1024字节,此时多四个自己无所谓。
一个对象体积是4字节,此时多4个字节相当于体积扩大一倍
2. 存在循环引用的问题

接下来如果 a 和 b 引用销毁,此时1号对象和2号对象引用计数都-1,但是结果都还是1,不是0,但是虽然不是0,不能释放内存,但是实际上这俩对象已经没有办法被访问到了。
Python/PHP,使用引用技术需要搭配其他的机制来避免循环引用。

 

就一个例子就是通过找到藏宝图来找到宝藏

这两个互相指向对方,除了他俩,谁也找不到他们, 此时这俩就是垃圾, 但是由于引用计数不是0, 还不能释放内存

 

6.1.1.2 可达性分析(java)

java中的对象都是通过引用来指向并访问的。经常是一个引用指向一个对象,这个对象里的成员又指向别的对象。

class TreeNode{
    int value;
    TreeNode left;
    TreeNode right;
}


整个 JAVA 中所有的对象就通过类似于上述的关系,通过这种链式/树形结构整体给串起来。
可达性分析就是把所有这些对象被组织的结构视为是树, 就从树根节点出发, 遍历树, 所有能被访问到的对象标记成“可达“(不能被访问到的就是“不可达“)
 JVM 自己有一份所有对象的名单,通过上述遍历把"可达"的标记出来了,剩下的"不可达"的就可以作为垃圾进行回收了。

举个栗子:

此时有 root 进行引用,就会有如下的效果(此处的可达性分析就是从 root 出发,尽可能进行遍历, 所有能够被访问到的对象就是可达)

root => a
root.left => b
root.left.left => d
root.left.right => e
root.left.right.left => g
假设此时
root.right.right = null   会导致 f 不可达,此时 f 就是垃圾
root.right = null   会导致 c 不可达, 如果 c 不可达, f 也一定不可达
 

可达性分析需要进行类似“树遍历“,这个操作相比引用计数来说肯定会慢一些,但是速度慢没关系,上述可达性分析遍历操作并不需要一直执行,只需要每隔一段时间,分析一遍就可以了。

进行可达性分析遍历的起点, 被称为 GCroots

1. 栈上的局部变量

2. 常量池中的对象

3. 静态成员变量

6.2 JVM 如何清理垃圾

如何清理垃圾?主要是以下三种做法

1. 标记清除

2. 复制算法

3. 标记整理

6.2.1 标记清除

简单粗暴,内存碎片问题。被释放的空闲空间是零散的,不是连续的 申请内存要求的是连续空间,总的空闲空间可能很大但是每一个具体的空间都很小,可能导致申请大一点的内存的时候就会失败,例如总的空闲空间是 10k 分成 1k 一个,总共十个,此时如果申请 2K 内存就会申请失败。 

6.2.2 复制算法

 

每次触发复制算法, 都是向另外一侧进行复制, 内存中的数据拷贝过去

缺点:

1. 空间利用率低

2. 如果垃圾少, 有效对象多, 复制成本比较大

6.2.3 标记整理

优点: 保证了空间利用率, 同时解决了内存碎片的问题

缺点: 效率不高, 如果要搬运的空间比较大, 此时开销也比较大 

 

6.2.4 分代回收

基于以上三种基本策略, 搞了一个复合策略"分代回收"。
把垃圾回收分成不同的场景,有的场景用这个算法,有的场景用那个算法各展所长。
分代回收是怎么分的?
基于一个经验规律:如果一个东西存在的时间比较长了, 那么大概率还会继续长时间持续存在下去(要消失的话早都要消失了,既然存在肯定还是有用的)
注意:规律不等于“定律“允许例外针对大部分情况是有效的。
上述规律,对于 JAVA 的对象也是有效的。
JAVA 的对象要么就是生命周期特别短的, 要么就是特别长的,根据生命周期的长短分别使用不同的算法,给对象引入一个概念,年龄(单位不是年,而是熬过 GC 的轮次)
这个 GC 的轮次指的就是经历过了这一轮可达性分析的遍历,发现这个对象还不是垃圾,这就是熬过了一轮 GC

年龄越大, 这个对象存在的时间就越久

 

刚 new 出来,年龄是0的对象,放到伊甸区
熬过一轮 GC 对象就要被放到幸存区了,虽然看起来幸存区很小,伊甸区很大,但是一般都够放
根据上述经验规律,大部分的 JAVA 中的对象都是朝生夕死,生命周期非常短。
从伊甸区到幸存区使用的是复制算法。
幸存区之后也要周期性的接受 GC 的考验,如果变成垃圾就要被释放,如果不是垃圾拷贝到另一个幸存区
(这俩幸存区同一时刻只用一个)在二者之间来回拷贝使用的是复制算法,由于幸存区体积不大,此处的空间浪费也能接受。
如果这个对象已经在两个幸存区中来回拷贝很多次了,这个时候就要进入老年代了。
老年代都是年纪大的对象,生命周期普遍更长,针对老年代也要周期性 GC 扫描,但是频率更低了,如果老年代的对象是垃圾了,使用标记整理的方式进行释放。


本文完,感谢观看,不足之处请在评论区指出 !

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

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

相关文章

Docker部署——将jar包打成docker镜像并启动容器

在代码编写完成即将部署的时候,如果采用docker容器的方法,需要将jar包打成docker镜像并通过镜像将容器启动起来。具体的步骤如下。 一、首先下载java镜像 先使用docker search java命令进行搜索。 然而在拉取镜像的时候要注意不能直接去选择pull java ,…

在线DDL操作踩坑记录

官方地址:GitHub - github/gh-ost: GitHubs Online Schema-migration Tool for MySQL 使用ghost方式在线对mysql表进行ddl ghost原理: 要对表A进行DDL,在主库建立一个ghost表 A1在表A1上进行alter操作伪装成一个mysql的从库,监…

Java集合框架:队列、Queue和Deque详解

目录 一、普通队列 1. 概念 2. Queue(Java集合框架的接口) 3. Queue中的方法 4. 方法使用演示 5. 队列的模拟实现 6. 顺序普通队列的缺点: 二、循环队列 1. 循环队列也是一种数据结构。基于上述队列的缺点,此时就有了循环…

为什么我不建议你入行网络安全,因为99.9%的人都绕不过这三个坎

前言 我一个朋友老赵,老赵在一家大型互联网公司做高级网络安全工程师,从实习生到工程师整整呆了六年。去年他们公司为了缩减成本,做了裁员,他也在其中,取而代之的是一个只有三年工作经验的 “新人” … 老赵想着&…

Windows10下安装Oracle19c提示“无法将 **\** 安装用户添加到 ** 组“解决办法

问题描述 操作系统:window10 数据库版本:Oracle19c 本机在安装Oracle19c提示无法将 ZHOUQUAN\zhouquan 安装用户添加到 %2% 组。 问题原因 根据安装的对话框中的日志,找到并打开 日志报错信息: 信息: WindowsSecurityExcep…

时序预测 | Matlab实现INFO-ELM向量加权算法优化极限学习机时间序列预测

时序预测 | Matlab实现INFO-ELM向量加权算法优化极限学习机时间序列预测 目录 时序预测 | Matlab实现INFO-ELM向量加权算法优化极限学习机时间序列预测效果一览基本介绍程序设计学习总结参考资料 效果一览 基本介绍 Matlab实现INFO-ELM向量加权算法优化极限学习机时间序列预测 …

skywalking 源码

源码核心是SkyWalkingAgent 找到一堆插件,来对符合条件的类来代理 通过AbstractClassEnhancePluginDefine.define方法来。 如果有很多版本的插件,spring有2.0版本,3.0版本,4.0版。 具体使用哪个版本,看被增加的类使用的是哪个版本的spring …

vue基础--计算商品的总价格

计算商品的总价格: 1、在 父组件中 通过计算属性 动态把总价格计算出来, 2、通过 父向子传值,通过自定义属性,把值传给 子组件 父组件: 1、使用计算属性computed 计算总价格: 1.1、先用filter 过滤出 数…

Unity UGUI5——图集

一、Drawcall ​ 字面理解 DrawCall,就是绘制呼叫的意思,表示 CPU(中央处理器)通知 GPU(图形处理器-显卡) (一)DrawCall 概念 就是 CPU (处理器)准备好渲染…

基于Web的停车场管理系统(Java)

目录 一、系统介绍 1.开发的环境 2.本系统实现的功能 3.数据库用到的表 4.工程截图 二、系统展示 1、登录页面 2、首页 3、系统信息管理模块 4、车位信息管理模块 5、IC卡信息管理模块 ​编辑6、固定车主停车管理模块 7、临时车主停车管理模块 8、系统功能操作模块 …

unity3d:小地图UV,UGUIshader毒圈挖孔,缩圈

运行效果 场景中缩圈 小地图中挖孔 大地图中挖孔 小地图 方案1使用Mask 给了一个方形的mask组件,然后根据玩家位置计算出地图左下角的位置进行移动。这种实现方式虽然简单,但是会有两个问题: 1.Overdraw特别大,几乎很多时候会有…

【LLMs 入门实战 】Vicuna 模型学习与实战

UC伯克利学者联手CMU、斯坦福等,再次推出一个全新模型70亿/130亿参数的Vicuna,俗称「小羊驼」,小羊驼号称能达到GPT-4的90%性能。 欢迎使用小羊驼🦙环境搭建权重下载下载 Vicuna Weight下载 LLAMA Weight构建真正的 working weigh…

Lattice Planner从入门到放弃

Lattice Planner相关背景和更正式的公式推导可以直接参考其原始论文《Optimal Trajectory Generation for Dynamic Street Scenarios in a Frent Frame》(ICRA 2010),本文侧重于Lattic planner理论和代码的结合。 1. Lattice Planner基本流程…

2023年6月GESP能力等级认证C++一级真题

2023-06 GESP一级真题 题数:27 分数:100 测试时长:60min 一、选择题(每题 2 分,共 30 分) 1.以下不属于计算机输入设备的有 (B ) 。(2分) A、键盘 B、音箱 C、鼠标 D、传感器 答案解析&#xff1…

如果你正在做AI测试,那么这十点你必须注意

AI是一个已经进入人类日常生活的新技术时代,例如Siri,Alexa语音接口等。通过大数据和数据科学实现数据存储的进步,使用户能够进行快速分析和数据检索。机器学习是一个新领域,机 AI是一个已经进入人类日常生活的新技术时代&#x…

今天我们来说说MySQL的缓存机制

原文链接:http://www.ibearzmblog.com/#/technology/info?id5770c555acd4302f81d86976c06e2319 前言 当我们向数据库服务器发送一条SQL的时候,但数据库收到后就会执行,但是如果在短时间内都执行同一条SQL,如果每次数据库都会执…

CUDA和显卡驱动以及pytorch版本的对应关系

1 支持CUDA 的GPU 支持 CUDA 的 NVIDIA Quadro 和 NVIDIA RTX CUDA GPU | NVIDIA Developer您的 GPU 计算能力 您是否正在寻找 GPU 的计算能力然后查看以下表格。您可以在这里了解更多 计算能力 。 NVIDIA GPU 为全球数百万台台式机笔记本电脑工作站和超级计算机提供动力加速…

《计算机网络——自顶向下方法》精炼——4.4.3-4.4.5

学习是终身的职业。在学习的道路上,谁想停下来就要落伍。 文章目录 UPnP因特网控制报文协议(ICMP)IPv6IPv6数据报格式IPv4到IPv6的变革 UPnP 通用即插即用(UPnP)提供了一种让外部网络的主机与NAT内主机交换数据的方式…

六十分之十七———低头拉车后的抬头看路

目录 前言:一、目标二、计划三、完成情况四、提升改进(最少3点)五、意外之喜(最少2点)六、总结 前言: 距离上次的月总已经过去四个多月时间了,这段时间里又是一次阶段性的下沉和突破,于是也就有了现在的总结。 此时还想将自己17…

未来10年,网络安全人才就业的黄金期

随着大数据、物联网、人工智能等新技术的发展,信息技术与经济社会各领域的融合也更加深入。网络攻击行为日趋复杂、黑客攻击行为组织性更强、针对手机无线终端的网络攻击日趋严重,近几年有关网络攻击和数据泄露的新闻层出不穷。因此,随着国家…