万字长文!非常详细!操作系统【内存管理】

在这里插入图片描述

在这里插入图片描述

🌈个人主页:godspeed_lucip
🔥 系列专栏:OS从基础到进阶

本文配套PDF文件,请浏览至文章底部下载。


  • 1 内存管理基础概念
    • 1.1 总览
    • 1.2 内存管理应有的功能
      • 1.2.1 内存空间的分配和回收
      • 1.2.2 从逻辑上扩充内存
      • 1.2.3 地址转换
      • 1.2.4 内存保护
    • 1.3 知识总结
  • 2 覆盖与交换
    • 2.1 总览
    • 2.2 覆盖技术
      • 2.2.1 覆盖技术的基本思想
      • 2.2.2 例子
      • 2.2.3 缺点
    • 2.3 交换技术
      • 2.3.1 基本思想
      • 2.3.2 待解决的问题
    • 2.4 总结
  • 3 连续内存分配
    • 3.1 总览
    • 3.2 单一连续分配
      • 3.2.1 思想
      • 3.2.2 优点
      • 3.2.3 缺点
    • 3.3 固定分区分配
      • 3.3.1 基本思想
      • 3.3.2 分类
      • 3.3.3 特点
      • 3.3.4 如何管理固定分区
      • 3.3.5 优缺点
    • 3.4 动态分区分配
      • 3.4.1 基本思想
      • 3.4.2 记录内存使用情况的数据结构
      • 3.4.3 空闲分区的分配
      • 3.4.4 分区的分配和回收
  • 4 基本分页存储管理的基本概念
    • 4.1 总览
    • 4.2 什么是分页存储
      • 4.2.1 将物理空间分页
      • 4.2.2 将逻辑空间分页
      • 4.2.3 空间的分配
      • 4.2.4 区分概念
    • 4.3 页表
      • 4.3.1 概述
      • 4.3.2 页表项的大小
      • 4.3.3 如何实现地址的转换
      • 4.3.4 如何确定一个逻辑地址对应的页号、页内偏移量
    • 4.4 总结
  • 5 基本地址变换机构
    • 5.1 概念
    • 5.2 变换步骤
      • 5.2.1 页表寄存器(PTR)
    • 5.3 变换步骤
    • 5.4 获取物理地址
      • 5.4.1 几个基本概念
      • 5.4.2 转换例题
      • 5.4.3 注意
    • 5.5 总结
  • 6 具有快表的地址变换机构
    • 6.1 总览
    • 6.2 什么是快表
    • 6.3 引入快表后,地址的变换过程
    • 6.4 与快表命中率有关的题目
    • 6.5 局部性原理
      • 时间局部性
      • 空间局部性
    • 6.6 知识总结
  • 7 两级页表
    • 7.1 知识总览
    • 7.2 单极页表存在的问题
      • 7.2.1 假设
      • 7.2.2 结论
    • 7.3 对第一个问题的解决
      • 7.3.1 思路
      • 7.3.2 原理
      • 7.3.3 逻辑结构的改变
      • 7.3.4 如何进行寻址
    • 7.4 对第二个问题的解决
    • 7.5 其他需要注意的细节
    • 7.6 总结
  • 8 基本分段存储管理方法
    • 8.1 总览
    • 8.2 分段的基本概念
      • 8.2.1 定义
      • 8.2.2 特点
      • 8.2.3 实例
      • 8.2.4 逻辑地址结构
    • 8.3 段表的基本概念
      • 8.3.1 示意图
      • 8.3.2 段表的特点
    • 8.4 地址的变换过程
    • 8.5 分段、分页管理的区别
      • 8.5.1 存储逻辑的区别
      • 8.5.2 分段的优点
      • 8.5.3 访问一个逻辑单元的访存次数
    • 8.6 总结
  • 9 段页式管理方法
    • 9.1 总览
    • 9.2 分段、分页的优缺点
    • 9.3 段页式管理的基本概念
    • 9.4 段页式管理的逻辑地址结构
      • 9.4.1 结构划分
      • 9.4.2 解释
      • 9.4.3 注意
    • 9.5 段页式管理中的段表和页表
      • 9.5.1 段表
      • 9.5.2 页表
      • 9.5.3 总结
      • 9.5.4 示意图
    • 9.6 地址转换过程
    • 9.7 总结
  • 10 总结


1 内存管理基础概念

1.1 总览

image1

1.2 内存管理应有的功能

1.2.1 内存空间的分配和回收

示意图:
image2

1.2.2 从逻辑上扩充内存

试想,随便下载一个大软件,其大小远远超过我们的内存大小,那么为什么这个软件可以运行呢?原因是操作系统采用了虚拟内存,即使物理空间较小,但是逻辑空间却可以很大。

1.2.3 地址转换

提供地址转换功能,负责程序的逻辑地址与物理地址的转换

image3
三种装入方式为:
image4

1.2.4 内存保护

提供内存保护功能,保证各进程在各自存储空间内运行,互不干扰。
使进程只可以访问属于自己的空间,不能去访问系统内核、其他进程的内存空间。那么,如何才可以实现内存保护呢?
以下图的进程1为例子
image5
(1)设置上下限寄存器。
image6
例如,进程1的实际物理地址为100-279,那么下限寄存器应该存放100,上限寄存器应该存放279。

(2)重定位寄存器、界地址寄存器
image7
重定位寄存器存放进程的实际物理地址的下限,界地址寄存器存放进程所需的最空间。例如,进程1的重定位寄存器存放100,界地址寄存器存放179-0=179。

1.3 知识总结

image8

2 覆盖与交换

2.1 总览

image1

2.2 覆盖技术

2.2.1 覆盖技术的基本思想

image2

2.2.2 例子

image3
如图,这是一个程序的结构调用图。可以看到,A是程序运行所必须的代码段,因此放在固定区内;B、C不可能同时运行,因此可以分配同一个覆盖区,D、E、F同理。如图所示
image4
因此,本来应该将代码全部放入,但是操作系统只分配了一部分空间就实现了全部放入的结果,因此从逻辑上看,操作系统的内存大小是被拓展了的。

2.2.3 缺点

image5

2.3 交换技术

2.3.1 基本思想

image6
比如说,假设内存中有进程1、2、3,如图
image7
此时内存紧张,进程1、2需要暂时换出外存,因此在内存保留它们的PCB后(方便操作系统的后续管理)将它们置于挂起队列,空出的内存空间给更为紧张的进程使用。

2.3.2 待解决的问题

image8
对于问题1:
image9
磁盘空间的示意图:
image10

对于问题2:
image11

对于问题三
image12

2.4 总结

image13

3 连续内存分配

3.1 总览

image1

3.2 单一连续分配

3.2.1 思想

image2
如图:
image3

3.2.2 优点

image4
一个进程独占内存,就不会发生进程访问其他进程的内存空间的情况,且即使进程访问了操作系统的内核程序,通常也可以通过重启解决,所以这种方式下不一定需要采取内存保护?

3.2.3 缺点

image5

3.3 固定分区分配

3.3.1 基本思想

image6

3.3.2 分类

根据分配的空间相等与否可以分为以下两类
image7
如图
image8

3.3.3 特点

image9

3.3.4 如何管理固定分区

可以通过分区说明表进行管理,其具体内容如图:
image10
这种数据结构可以通过数组或链表实现
image11

3.3.5 优缺点

image12

3.4 动态分区分配

3.4.1 基本思想

image13

3.4.2 记录内存使用情况的数据结构

可以采取空闲分区表、空闲分区链表示
(1)空闲分区表
例子:
image14
image15
(2)空闲分区链
例子:
image16

3.4.3 空闲分区的分配

分配算法在下一小节进行详细描述
image17

3.4.4 分区的分配和回收

假设操作系统采用空闲分区表管理分区(使用空闲分区链同理)
(1)分配操作
假设起始表内容如下:
image18
①假如一个空闲分区的大小大于进程申请的空间,那么直接修改内容和即可。 假设一个4MB的进程进入,需要分配到分区1中,那么分区表应该修改如下:
image19

②假如一个空闲分区的大小等于进程申请的空间,那么需要删除该内容。假设一个4MB的进程进入,需要分配到分区3中,那么分区表应该修改如下:
image20

(2)回收操作
①回收分区的后面(后面)有空闲分区
直接修改表项内容
image21

②回收分区的后面没有空闲分区
增加一个表项内容
image22

③回收分区的前后均为空闲分区
合并表项内容
image23

注意:各表项的排序不一定按照分区地址的大小进行排序

4 基本分页存储管理的基本概念

4.1 总览

image1

4.2 什么是分页存储

4.2.1 将物理空间分页

image2

4.2.2 将逻辑空间分页

image3
方便管理员进行管理

4.2.3 空间的分配

image4

4.2.4 区分概念

image5

4.3 页表

4.3.1 概述

(1) 必要性
image6
(2) 示意图
image7
(3) 注意
image8

4.3.2 页表项的大小

(1)块号的字节
假设:
image9
由于内存块的大小(物理)=页面大小(逻辑) = 4KB = 212B,则一个4GB的内存总共会被分为232/2^12 = 220块,则内存块号的范围应该是0-220-1,需要使用20个Bit存储,也就是至少需要3个字节(24B)进行存储。
(2)页号的字节
由于页表项是连续存储的,因此只要知道页号以及页表的起始地址就可以计算得到目的页号的块号,因此页表不需要存储页号,字节为0。
(3)综上,每一个页表项占3字节(在题中所给条件上)
(4)注意
image10
并不存储物理地址

4.3.3 如何实现地址的转换

(1)虽然进程的各个页面是离散存放的,但是页面内部是连续存放的
image11
(2)转换步骤:
image12

4.3.4 如何确定一个逻辑地址对应的页号、页内偏移量

(1)例子:
image13
我们知道,对于一个进程来说,各页面是离散存放的,但是在逻辑上各页面是连续存放的。页面内部不管是物理上还是逻辑上都是连续存放的。如图:
image14
据此可以快速得到地址的转换逻辑:
image15

(2)拓展
image16
假设一个计算机是用32个二进制位表示逻辑地址,页面大小位4KB = 2^12B = 4096B
那么,进程数据的逻辑地址的后12位为页面偏移量,逻辑地址的前20位是页号,比如:
image17

(3)我们知道,n号内存块的起始地址 = n*内存块大小。以我们刚才的例子为例:
image18
则逻辑地址的后12位为业内偏移量,前20位为页号。由此我们可以得到结论:
image19

4.4 总结

image20

5 基本地址变换机构

5.1 概念

基本地址变换机构是一组用于实现逻辑地址到物理地址转换的硬件机构

5.2 变换步骤

5.2.1 页表寄存器(PTR)

image1

5.3 变换步骤

假设页面的大小为2的整数次幂。当一个进程发生调度需要上处理机运行时,操作系统会将恢复进程的运行环境,将进程的PCB(存放页表的地址与页表的长度)放入页面寄存器中以方便操作系统进行管理,此外,程序计数器PC也会将进程下一条需要执行的指令的逻辑地址A放入,那么如何知道进程下一条指令的物理地址呢?

5.4 获取物理地址

(1)转换机构根据逻辑地址计算出页号P、页内偏移量W。假如页面大小为2的整数次幂,那么这个过程是很方便的
(2)假如一个进程的页表长度为M,意味着这个进程有M个页面,假如P>M,那么说明出错,操作系统会发生越界终端(内中断)
(3)确定M合法后,操作系统查询页表并找到页号对应的页表项,确定页面存放的内存块号。
(4)使用内存块号和页内偏移量计算得到物理地址(直接拼接),此时就可以访问内存单元了。
变换步骤如图:
image2

5.4.1 几个基本概念

页表项长度、页表长度、页面大小。
image3

5.4.2 转换例题

image4

5.4.3 注意

image5

三、对页表项大小的进一步探讨
image6
所以,尽管3个字节已经可以表示所有的内存块,但是为了计算方便,经常会将页表项扩充为四个字节
image7

5.5 总结

image8

6 具有快表的地址变换机构

6.1 总览

image1

6.2 什么是快表

image2

6.3 引入快表后,地址的变换过程

1. 快表是一种硬件设备,它的内容在每次进程切换之后都会删除,它的访问速度虽然很快,但是由于成本的限制,快表的存储空间不会很大。

2. 引入快表后,操作系统在得到逻辑地址后会分离得到页号,接着进入快表去寻找页号对应的内存块号,假如没找到就会进入慢表(也就是之前的页表)进行寻找,并将寻找结果复制一份存入快表有方便下次寻找。其他步骤与无快表的地址变换过程类似。
image3

3. 示意图如下所示:
image4

6.4 与快表命中率有关的题目

image5

6.5 局部性原理

我们以下面这段代码为例:
image6

时间局部性

image7
对于while(i<100)这一条指令,程序在不久的将来是会频繁访问的,对于i这个变量,程序在不久的将来也是会频繁访问。这就是时间局部性。

空间局部性

image8
对于a数组,它在内存中是连续存放的,假如此时系统访问了a[10],那么a[10]周围的数据就很有可能会被频繁访问。这是空间局部性。

3. 正是因为局部性原理,引入快表之后系统的速度就会快很多
image9

6.6 知识总结

image10

7 两级页表

7.1 知识总览

image1

7.2 单极页表存在的问题

7.2.1 假设

image2
页面大小为4KB,即212的字节,因此需要12个二进制位来存储,该计算机就支持32位,因此有20个二进制位表示页号,即可以表示220个页面,每个页面在页表中都必须对应一个页表项,因此页表中的页表项最多可以有220个,所以一个页表需要的最大空间为220*4 = 222B,而为了存储页表必须需要(222)/(2^12) = 2^10个连续的页框(页表必须连续存放)。
image3

7.2.2 结论

image4

7.3 对第一个问题的解决

7.3.1 思路

为了解决单极页表存在的几个问题,可以考虑将页表也进行分页并离散存储(单击页表中是将进程的页面离散存储)。

7.3.2 原理

对于给定的计算机配置信息(按字节寻址,支持32位,页面大小为4kb,页表项长度为4b),一个进程最多有220个页面,而每个页框可以存储的页表项个数为4kb/4b=210 = 1024个页表项。由此,可以将页表的2^20拆分成1024组,每组有1024个页表项,用一个二级页表存储单级页表,

7.3.3 逻辑结构的改变

32位二进制位中,前10位用来表示二级页表,后10位用来表示每个二级页表包含的单极页表,最后12位表示页面偏移量。

7.3.4 如何进行寻址

简单来说就是逐个寻找,先找一级地址,再在一级地址内找二级地址,最后根据页面偏移量找到对应的物理地址
image5

7.4 对第二个问题的解决

image6
当需要的页面不在内存中时会发生缺页中断(这是一个内中断),接着将目标页面从外存调入内存。

7.5 其他需要注意的细节

1. 各级页表的大小不可以超过一个页面。如果分为两级页表后,各级页表还是超过一个页面,则应该采用更多的顶级页表。
TIPS:如果一个页表分为了好几页,那么不同页中可能页号有重叠,可能会照成无法区分顶级页表的后果。

例子:
image7
业内偏移量位数实质上就是需要用几位二进制位来表示页面大小。这里4kb = 2^12,因此需要12位。每个页面包含的页表项个数位4kb/4b = 2^10个,因此一个页面最多可以包含10个二进制位。
由于页内偏移量为12位,因此页号位数为28位,而每级页表最多表示10位,因此此题需要分三级页表,分别占:8、10、10。逻辑结构如图:
image8

2. 假如没有快表结构,那么N级页表访问一个逻辑地址需要经历N+1次访存,其中,依次访问各级页需要N次,最后得到了逻辑地址对应的物理地址后还需1次访存。

7.6 总结

image9

8 基本分段存储管理方法

8.1 总览

image1

8.2 分段的基本概念

8.2.1 定义

image2
类比于程序,其中的main函数是一段,而定义在main函数之外的其他函数也是一段。

8.2.2 特点

(1)当采用分段存储时,各段可以离散的存储,但是一个特定的段占据连续的内存空间。
(2)由于是按照逻辑功能划分模块,用户的编程更加方便,程序的可读性更加高。
(3)在编译程序时,系统会将段名转换为段号。

8.2.3 实例

image3

8.2.4 逻辑地址结构

image4
实例:对于编译后的机器汇编语言:
image5

8.3 段表的基本概念

8.3.1 示意图

image6
段表的作用类似于页表,记录各段的物理存储位置

8.3.2 段表的特点

(1)与页表类似,由于段在逻辑上在连续存储的,所以段号实际上是不需要被保存的。
只需记录段长以及各段的长度(基址)
image7

(2)段表项的长度是固定的。如果段的逻辑结构中段内地址为16位,系统使用16个二进
制位就可以表示最大段长;而系统的物理地址肯定也对应一个最大字节长度(假设为4GB,
对应32位);段号无须存储。因此可以让每个段表项占16+32=48位,即6个字节。
image8

8.4 地址的变换过程

1. 进程在发生切换时,其PCB会被放入段表寄存器。系统在得到逻辑地址后,将其分解为段号S、段内地址W。
2. 首先检查段号是否合法(段号是否越界)。假如S是否>=段表长度M(从段表寄存器中读取),那么段号越界,系统发生越界中断。注意此处因为段表长度至少为1,而段号从0开始,所以当S=M时也相当于越界。
3. 将段号在段表中进行匹配,并得到段长C,此时如果W>=C,那么段长越界,发生越界中断。注意当采用页表时此处无须比较,因为页表的各页表项的长度是固定的,但是段表的段长是不固定的。假如没有越界,那么就取出基址,将基址与段内地址相加得到最后的物理地址。
4. 示意图如下所示:
image9

8.5 分段、分页管理的区别

8.5.1 存储逻辑的区别

image10

8.5.2 分段的优点

分段比分页更容易实现信息的共享和保护

(1)信息的共享
假设计算机采用分段管理,且有这样一段代码空间
image11
其中1号段是A、B号进程都想访问的,那么只需让各进程的段表项指向同一个段即可实现共享
而假如计算机采用分页管理,那么上述的代码空间应变为:
image12
页面不是按照逻辑模块划分的,此时就很难实现信息的共享
(2)信息的保护
与信息共享类似,假如进程A不允许某个进程访问某个空间,只需将这段置标记为不可访问即可。而分页管理就很难实现

8.5.3 访问一个逻辑单元的访存次数

image13

8.6 总结

image14
image15

9 段页式管理方法

9.1 总览

image1

9.2 分段、分页的优缺点

image2
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.3 段页式管理的基本概念

image4
比如说:
image5

9.4 段页式管理的逻辑地址结构

9.4.1 结构划分

image6

9.4.2 解释

image7

9.4.3 注意

image8

9.5 段页式管理中的段表和页表

9.5.1 段表

基本结构:
image9
由于各段被分为几页是不确定的,因此需要记录页表的长度,同时为了确定物理地址,还需要存放页表的起始地址(页表存放块号)。每一个段需要对应一个页表。
从图中可以看出,每个段表项的长度是相同的(只需记录页表长度即起始块号),因此段号是可以隐藏的。

9.5.2 页表

基本结构
image10
页面的大小都是相同的,因此页号是隐藏的。只需记录各页号对应的内存块号即可。
image11

9.5.3 总结

一个进程会被划分为多个段,所有的段构成一段表。而每一个段会被划分为多个页面,因此一个段对应一个页表。
总结:一个进程对应一个段表,但对应多个页表。

9.5.4 示意图

image12

9.6 地址转换过程

首先,进程被调度时,其PCB中的段表起始地址F与段表长度M都会被复制放入操作系统的段表寄存器中;
接着读出逻辑地址中的段号S,并与段表长度进行比较,假如S>=M,(这里的=与前面的段式管理类似)说明越界,产生越界中断。
段号合法后,操作系统根据段表起始地址F查询到该进程对应的段表,根据段号查询到对应的段表项,
操作系统从逻辑地址读出页号P,并于段表项中的页表长度L进行对比,假如P>L,说明页号越界,产生越界中断。
页号合法后,操作系统从段表项中读出页表起始地址,根据页号查询页表得到内存块号,并结合逻辑地址中的业内偏移量得到最终的物理地址并访问。
具体过程示意图如下:

image13

访存过程中,操作系统共需要访问三次内存。第一次是查询段表,第二次是查询页表,第三次是访问目标地址。我们也可以引入快表,以段号和页号作为关键字。

9.7 总结

image14

10 总结

配套PDF资料下载:提取码·:ikun

操作系统,如默默守护的守夜者,无声地管理硬件与软件的交流,为计算机创造和谐秩序。

它是无形的引导者,让复杂的任务变得井然有序,为用户提供无忧体验。

操作系统的巧妙设计,让计算机变得更加智能高效,让人与科技之间的交流更加顺畅。

在每一次启动中,它如信任的伙伴,带领我们进入数字世界的奇妙旅程。

渴望挑战操作系统的学习路径和掌握进阶技术?不妨点击下方链接,一同探讨更多操作系统的奇迹吧。我们推出了引领趋势的💻OS专栏:《OS从基础到进阶》 ,旨在深度探索OS的实际应用和创新。🌐🔍

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

品牌/企业/人物百度百科创建攻略:一文掌握百度百科创建与审核要点

在数字化时代&#xff0c;百科全书已经成为大众获取知识和信息的重要渠道。无论是品牌、企业还是个人&#xff0c;拥有一个专属的百度百科词条&#xff0c;不仅可以提升知名度&#xff0c;还可以展现自己的实力和特色。那么&#xff0c;如何创建百度百科词条&#xff0c;并通过…

windows安装Mysql解压版

windows安装Mysql解压版 一、下载mysql-8.0.36-winx64.zip二、解压三、配置3.1. 添加环境变量&#xff1a;新建MYSQL_HOME3.2.如何验证是否添加成功&#xff1a;必须以管理员身份启动3.3. 初始化MySQL&#xff1a;必须以管理员身份启动3.4. 注册MySQL服务&#xff1a;必须以管理…

【软考中级备考笔记】数据的表示和校验码

2024/2/18 – 数据的表示和校验码 天气&#xff1a;阴雨 春节假期结束后第一个工作日&#xff0c;开始备考中级软件工程师。 希望在今年5月底的软考中取得中级证书 视频地址&#xff1a;https://www.bilibili.com/video/BV1Qc411G7fB 1. 计算机的总体架构 从下图中可以看出&am…

文件上传漏洞--Upload-labs--Pass03--特殊后缀与::$DATA绕过

方法一&#xff1a;特殊后缀绕过&#xff1a; 一、什么是特殊后缀绕过 源代码中的黑名单禁止一系列后缀名 之外的后缀&#xff0c;称之为‘特殊后缀名’&#xff0c;利用其来绕过黑名单&#xff0c;达到上传含有恶意代码的文件的目的。 二、代码审计 接下来对代码逐条拆解进行…

网络安全实验(三)

1.办公区设备可以通过电信和移动两条链路上网&#xff0c;且需要保留一个公网ip不能用来转换 2.分公司设备可以通过两条链路访问到dmz区域的http服务器 3.分公司内部客户端可以通过公网地址访问到内部服务器 4.FW1和FW3组成主备模式的双击热备 5.办公区上网用户限制流量不超…

鸿蒙开发系列教程(二十四)--List 列表操作(3)

列表编辑 1、新增列表项 定义列表项数据结构和初始化列表数据&#xff0c;构建列表整体布局和列表项。 提供新增列表项入口&#xff0c;即给新增按钮添加点击事件。 响应用户确定新增事件&#xff0c;更新列表数据。 2、删除列表项 列表的删除功能一般进入编辑模式后才可…

东方通TongWeb启动报cache问题解决

启动东方通&#xff0c;应用系统报错如下&#xff1a; [Unable to add the resource at [/WEB-INF/lib/ojdbc6-11.2.0.3.jar] to the cache because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum si…

华清远见作业第三十六天和第三十七天——C++(第五天和第六天)

思维导图&#xff1a; 第五天&#xff1a; 第六天&#xff1a; 作业&#xff1a; 编程题&#xff1a; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;…

Office2019办公软件Word文档、Excel表格、PPT幻灯片图标文件图标变成全白色的白板了

原因可能是下载安装过WPS&#xff0c;office图标变白是由于卸载了其他版本的office软件或者是WPS后&#xff0c;重新安装没有删除以前的快捷方式所造成的&#xff0c;而以前的快捷方式找不到而变白。 解决方法&#xff1a; 1.将文件类型指定默认应用&#xff1b; 2. HKEY_CLA…

Java程序的运行机制

1、源文件“类名.java文件”是保存源代码的文本文件。 2、二进制字节码文件“类名.class文件”是使用javac命令编译得到&#xff0c;编译语法格式&#xff1a;javac 源文件名.java 3、字节码文件还不能够实现人工读取&#xff0c;因此还需要利用java.exe执行“类名.class文件”…

代码随想录day25--回溯的应用4

LeetCode491.非递减子序列 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;…

【完全二叉树节点数!】【深度优先】【广度优先】Leetcode 222 完全二叉树的节点个数

【完全二叉树】【深度优先】【广度优先】Leetcode 222 完全二叉树的节点个数 :star:解法1 按照完全二叉树解法2 按照普通二叉树&#xff1a;深度优先遍历 后序 左右中解法3 按照普通二叉树&#xff1a;广度优先遍历 层序遍历 ---------------&#x1f388;&#x1f388;题目链接…