操作系统内存管理
内存
内存被设计用来存储数据,以便程序在执行之前能够先被加载到内存中,进而被CPU高效地处理。这一机制有效地缓解了CPU与硬盘之间存在的速度差异和矛盾,确保了数据处理流程的顺畅进行。
一、内存管理
1. 进程运行的基本原理
在深入探讨内存管理的具体策略之前,我们首先需要深入理解进程运行的基本原理及其内在要求。
进程的创建始于程序与数据的内存装载过程,这一流程涉及将用户源代码转化为内存中可执行的程序,通常涵盖以下关键步骤:
- 编译过程。通过编译程序,用户的源代码被转化为多个目标模块,这些模块是程序执行的基础构件。
- 链接过程。链接程序负责将这些目标模块及其所需的库函数整合成一个完整的装入模块。这一步骤确保了程序在运行时能够访问所有必要的代码与数据。
- 装入过程。由装入程序负责将这一完整的装入模块加载至内存中,使其得以执行。
在程序的链接阶段,我们通常采用以下三种方式:
- 静态链接:即在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开。
- 装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式,以提高装载效率。
- 运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。
2. 内存管理的概念
内存管理(Memory Management)构成了操作系统设计中的核心且最为错综复杂的组成部分之一。尽管计算机硬件技术日新月异,内存容量持续扩增,然而,面对所有用户进程及系统所需程序与数据的海量存储需求,将所有内容同时载入主存仍属不可能之事。因此,操作系统必须承担起对内存空间进行合理划分与高效动态分配的重任,这便是内存管理的精髓所在。
在多道程序设计的框架下,有效的内存管理显得尤为重要。它不仅能够极大地简化用户对存储器的使用流程,提升内存资源的利用率,还能借助虚拟技术,在逻辑层面上实现存储器的扩容。
- 逻辑地址(相对地址):是程序编写和编译时用的地址,基于某个基准。
- 物理地址(绝对地址):则是数据在内存中实际存储的位置。
内存管理的核心功能涵盖 内存空间的分配与回收、 地址转换机制、 内存空间的虚拟扩充、 存储保护机制 四个方面。
(1)地址转换机制
地址转换机制:在多道程序并行的环境中,程序中的逻辑地址与内存中的物理地址往往并不一致。因此,存储管理系统必须提供地址变换的功能,确保逻辑地址能够准确无误地映射到相应的物理地址上。
- 绝对装入方式:编译时若已知程序内存位置,则生成绝对地址代码,装入程序据此将程序数据精准装载至指定内存位置,但仅适用于单道程序环境。
- 静态重定位方式(可重定位装入):编译链接后,模块地址以0为起点编排,装入时根据内存情况灵活装载,并一次性将逻辑地址转换为物理地址。需一次性分配全部内存,作业运行期间不可移动或再申请内存。
- 动态重定位方式(动态运行时装入):同样以0为起点编排地址,但装入后不进行立即转换,而是在程序执行时动态进行。需重定位寄存器支持,允许程序内存移动,提供更高灵活性与效率。
(2)存储保护机制
存储保护机制:这一功能确保了各个作业能够在其专属的存储空间内独立运行,避免了相互之间的干扰与冲突。
内存保护可采取两种方法:
- 在CPU中设置一对上、下限寄存器,存放进程的上、下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
- 采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址
(3)内存空间的虚拟扩充
内存空间的虚拟扩充 :借助虚拟存储技术或自动覆盖技术等手段,我们可以在逻辑层面上实现内存的扩容,从而满足更大规模的程序运行需求。
内存空间的虚拟扩充主要依赖于覆盖技术和交换技术。
-
覆盖技术:
此技术将程序细分为多个段或模块,以优化内存使用。其中,常用的段被设定为常驻内存,确保它们在程序运行期间始终可用。而不常用的段则被灵活处理,仅在需要时被调入内存,使用完毕后即被调出,以释放内存空间供其他任务使用。为实现这一机制,内存被划分为一个“固定区”和若干个“覆盖区”。固定区用于存放那些需要常驻内存的段,而覆盖区则用于动态地调入和调出那些不常用的段。
-
交换技术:
当内存空间变得紧张时,系统采用交换技术来优化内存资源的分配。这一技术的核心思想是,在内存与磁盘之间动态地调度进程。具体来说,系统会将内存中某些当前不活跃或优先级较低的进程暂时换出到磁盘上,以释放内存空间。同时,系统也会检查磁盘上那些已具备运行条件且优先级较高的进程,将它们换入内存,以便它们能够继续执行。通过这种方式,系统能够灵活地管理内存资源,确保高效运行。
(4)内存空间的分配与回收
内存空间的分配与回收:操作系统负责主存储器空间的分配与管理工作,从而减轻了程序员在存储分配方面的负担,进一步提高了编程效率。
内存空间的分配包括连续分配方式和非连续分类方式。
- 连续分配:指为用户进程分配的必须是一个连续的内存空间。
- 非连续分类方式:为用户进程分配的可以是一些分散的内存空间。
3. 连续分配方式
(1)单一连续分配
单一连续分配:将内存明确分为系统区和用户区。系统区位于低地址,存储操作系统核心数据;用户区则存放用户进程及数据。此方式下,内存中仅运行一道用户程序,确保运行独立性和完整性。其优点为实现简单、无外部碎片,且可通过覆盖技术扩展内存。但仅适用于单用户、单任务环境,内部碎片问题导致存储器利用率低。
(2)固定分区分配
固定分区分配:为解决多道程序运行问题,将用户空间划分为多个固定或不等大小的分区,每个分区仅装入一道作业。操作系统通过分区说明表管理分区,记录大小、起始地址和状态。此方式实现简单、无外部碎片,但当程序过大时可能找不到合适分区,需采用覆盖技术,且内部碎片降低内存利用率。
(3)动态分区分配
动态分区分配:又称可变分区分配,此方式更为灵活,不预先划分内存分区,而是根据进程大小动态划分。系统分区大小和数量可变,更有效地利用内存资源,提高存储器利用率。
在动态分区分配方式下,若存在多个空闲分区均能满足内存分配需求时,就需要借助动态分区算法来确定最合适的分区进行分配。
- 首次适应算法(First Fit):每次都从低地址开始查找,找到第一个能满足大小的空闲分区。此算法综合看性能最好,算法开销小 。
- 最佳适应算法(Best Fit):优先使用更小的空闲区,从而尽可能多地留下大片的空闲区。此算法可以保证当“大进程”到来时能有连续的大片空间。
- 最坏适应算法(Worst Fit):又称 最大适应算法(Largest Fit),在每次分配时优先使用最大的连续空闲区,从而防止分配后剩余的空闲区就太小。此算法可以尽可能少地留下太多难以利用的小碎片。
- 邻近适应算法(Next Fit):每次都从上次查找结束的位置开始检索,从而减小查找的开销。此算法开销较小并避免低地址部分出现很多小空闲分区。
4. 非连续分配方式
(1)基本分页存储管理(Paging)
固定分区会产生内部碎片,而动态分区会产生外部碎片,这两种技术对内存的利用率都不高。为了尽量避免碎片的产生,我们引入了分页的方法。
**分页(Paging)**是一种内存管理技术,通过将内存和进程的逻辑地址空间划分为大小相等的固定块来提高内存利用率,减少碎片的产生。
通过分页管理,操作系统可以将进程的逻辑地址映射到物理内存中的页框,从而提高内存利用率,减少碎片问题,并实现高效的内存管理。
分页管理的基本概念:
进程的逻辑地址空间被划分为若干大小相等的部分,每个部分称为页(Page)。页是逻辑地址空间的基本单位。页在进程逻辑地址空间中的编号被称为页号(Page Number),从0开始。
内存空间被划分为若干大小相等的分区,每个分区称为页框或页帧(Page Frame)。页框是物理内存的基本单位。页框在物理内存中的编号被称为页框号(Page Frame Number),从0开始。
操作系统为每个进程维护一张页表(Page Table),用于记录进程的每个页在物理内存中的存放位置。页表通常存储在进程控制块(PCB)中。每个进程对应一张页表。
内部碎片与内存交换策略
内存分页机制下,内存分配的最小单位是页,这意味着即使程序所需内存小于一页,也至少要分配一个完整的页,从而导致页内可能存在内存浪费现象,这被称为内部内存碎片。
当系统内存空间不足时,操作系统会智能地管理资源,通过释放那些最近未被使用的内存页面来腾出空间,即将其暂时写入硬盘,这一过程称为换出(Swap Out)。当这些页面再次被需要时,它们会被重新加载回内存这一过程称为称为换入(Swap In)。由于每次交换通常仅涉及少数一个或几个页面,因此写入磁盘的时间相对较短,从而确保了内存交换操作具有较高的效率。
基本地址变换机构
基本地址变换机构可以借助进程的页表将逻辑地址转换为物理地址。
当CPU需要访问一个虚拟地址时,它首先根据页号找到页表中的对应条目,然后从该条目中读取物理页框号。最后将物理页框号与页内偏移组合起来,形成物理地址。
然而,页表具有空间上的缺陷。操作系统能同时运行大量进程,这导致页表规模庞大。在32位系统中,若页面为4KB,则4GB虚拟地址空间需约100万个页表项,每项4字节,整个页表即占4MB。但每个进程均有独立虚拟地址空间及页表,因此100个进程便需400MB内存来存储页表,内存开销显著。到了64位环境,这一开销更是剧增。
为了解决这一问题,提出了二级页表。
二级页表通过两个层次的表结构来映射虚拟地址到物理地址。这两个层次分别是页目录和页表。页目录中的每一项都指向一个页表,而页表中的每一项则指向一个物理页帧。
(2)基本分段存储管理(Segmentation)
程序由多个逻辑部分构成,这些部分包括代码段、数据段、栈段和堆段等。鉴于各段具有不同的属性和功能,采用**分段(Segmentation)**技术将这些部分有效地区分开来,以确保程序的结构清晰且运行高效。
在分段机制下,虚拟地址到物理地址的映射过程涉及几个关键组件和步骤。
分段系统的逻辑地址结构由段选择因子和段内地址(段内偏移量)所组成。
- 段选择因子:通常保存在段寄存器中,它包含了段号,这个段号用作段表的索引来查找对应的段表,段号的位数决定了每个进程最多可以分几个段。
- 段内偏移量:在一个逻辑段内部,从段的起始位置到目标数据或指令位置之间的相对距离或偏移量。段内地址位数决定了每个段的最大长度是多少。
程序分多个段,各段离散地装入内存,为了保证程序能正常运行,就必须能从物理内存中找到各个逻辑段的存放位置。为此,需为每个进程建立一张段映射表,简称段表。每个段对应一个段表,其中记录了该段在内存中的起始位置(又称基址)、段的界限和特权等级。各个段表项的长度是相同的。
虚拟地址到物理地址的映射过程如下:
当CPU要访问一个虚拟地址时,它首先会根据段选择子在段表中找到对应的段的基地址,然后将段内偏移量与基地址相加,从而得到物理内存中的实际地址;如果段内偏移量是合法的(即位于0和段界限之间),则映射成功,CPU可以访问到相应的物理内存地址。
内存碎片:
内存分段管理是一种按需为程序分配内存空间的方法,其中内存碎片主要分为内部碎片和外部碎片。内部碎片因固定大小分配单元与实际需求不匹配而产生,在分段管理中通过按需分配段来避免;
外部碎片则由多个不连续小内存块导致新程序无法装载,可通过内存交换等技术解决。
当内存不足时,系统会将部分暂时不需要的内存数据写入硬盘上,从而腾出更多的内存空间供其他程序使用。当需要访问被交换出去的数据时,系统会将其重新调入内存。重新调入内存后,不会存到原来的位置,而是存到其他内存数据的旁边,以达到将内存碎片合并的目的。
(3)段页式存储管理
分段与分页的区别:
- 页是信息的物理单位。分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管理上的需要,完全是系统行为,对用户是不可见的。段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。一个段通常包含着一组属于一个逻辑模块的信息。分段对用户是可见的,用户编程时需要显式地给出段名。
- 页的大小固定且由系统决定。段的长度却不固定,决定于用户编写的程序。
- 分页的用户进程地址空间是一维的,程序员只需给出一个记忆符即可表示一个地址。分段的用户进程地址空间是二维的,程序员在标识一个地址时,既要给出段名,也要给出段内地址。
方式 | 优点 | 缺点 |
---|---|---|
分页管理 | 内存空间利用率高,不会产生外部碎片,只会有少量的页内碎片 | 不方便按照逻辑模块实现信息的共享和保护 |
分段管理 | 很方便按照逻辑模块实现信息的共享和保护 | 如果段长过大,为其分配很大的连续空间会很不方便;会产生外部碎片 |
所以可将内存分段和内存分页组合起来在同一个系统中使用,通常称为段页式内存管理。
段页式内存管理:将进程按逻辑模块分段,接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页。
用于段页式地址变换的数据结构是每一个程序一张段表,每个段又建立一张页表,段表中的地址是
页表的起始地址,而页表中的地址则为某页的物理页号,如图所示。
段页式地址变换中要得到物理地址须经过三次内存访问: 第一次访问段表,得到页表起始地址; 第二次访问页表,得到物理页号; 第三次将物理页号与页内位移组合,得到物理地址。
二、虚拟内存
1. 虚拟内存
(1)传统存储方式管理的特点与缺点
- 一次性:作业必须一次性全部装入内存后才能开始运行。这会造成两个问题
- 作业很大时,不能全部装入内存,导致大作业无法运行;
- 当大量作业要求运行时,由于内存无法容纳所有作业,因此只有少量作业能运行,导致多道程序并发度下降。
- 驻留性:一旦作业被装入内存,就会一直驻留在内存中,直至作业运行结束。事实上,在一个时间段内,只需要访问作业的一小部分数据即可正常运行,这就导致了内存中会驻留大量的、暂时用不到的数据,浪费了宝贵的内存资源。
(2)局部性原理
- 时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)
- 空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的,并且程序的指令也是顺序地在内存中存放的)
(3)虚拟内存(Virtual Memory)
基于局部性原理,在程序装入时,系统仅将程序的一部分载入内存,而将其余部分留在外存,从而启动程序的执行。
具体过程如下:
- 在程序运行过程中,当所需的信息不在内存中时,操作系统会将所需的部分调入内存,然后继续执行程序,此过程被称为请求调页功能;
- 操作系统会将内存中暂时不使用的内容换出到外存,以腾出空间存放即将调入内存的信息,此过程被称为页面置换功能。
在操作系统的这种管理方式下,在用户看来似乎有一个比实际内存大得多的内存,这就是虚拟内存(Virtual Memory),又被称为虚拟存储器。
虚拟内存之所以得名,是因为这个内存实际上并不存在。它通过系统提供的部分装入、请求调入和置换功能(对用户完全透明),使用户感觉仿佛存在一个比实际物理内存大得多的存储器。虚拟存储器的大小由计算机的地址结构决定,并不是简单地将内存和外存的容量相加。
虚拟内存有一下三个主要特征:
- 多次性:无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存。
- 对换性:在作业运行时无需一直常驻内存,而是允许在作业运行过程中,将作业换入、换出。
- 虚拟性:从逻辑上扩充了内存的容量,使用户看到的内存容量,远大于实际的容量。
(4)虚拟内存的实现
虚拟内存技术,允许一个作业分多次调入内存。如果采用连续分配方式,会不方便实现。因此,虚拟内存的实现需要建立在离散分配的内存管理方式基础上。
常用的方式有:请求分页存储管理、请求分段存储管理、请求段页式存储管理。
2. 请求分页管理方式
前面已经介绍过基本分页存储管理
请求分页存储管理与基本分页存储管理的主要区别:
- 在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序。
- 若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存。
(1)请求分页管理的页表
与基本分页管理相比,请求分页管理的页表中,需要保存更多信息:
- 为了实现“请求调页”,操作系统需要知道每个页面是否已经调入内存;如果还没调入,那么也需要知道该页面在外存中存放的位置。
- 当内存空间不够时,要实现“页面置换”,操作系统需要通过某些指标来决定到底换出哪个页面;有的页面没有被修改过,就不用再浪费时间写回外存。有的页面修改过,就需要将外存中的旧数据覆盖,因此,操作系统也需要记录各个页面是否被修改的信息。
(2)缺页中断机构
在请求分页系统中,每当要访问的页面不在内存时,便产生一个缺页中断,然后由操作系统的缺页中断处理程序处理中断。此时缺页的进程阻塞,放入阻塞队列,调页完成后再将其唤醒,放回就绪队列。
如果内存中有空闲块,则为进程分配一个空闲块,将所缺页面装入该块,并修改页表中相应的页表项;如果内存中没有空闲块,则由页面置换算法选择一个页面淘汰,若该页面在内存期间被修改过,则要将其写回外存。未修改过的页面不用写回外存。
缺页中断是因为当前执行的指令想要访问的目标页面未调入内存而产生的,因此属于内中断;一条指令在执行期间,可能产生多次缺页中断。
(3)地址变换机构
由请求分页管理与基本分页管理的区别可以看出,请求分页管理需要在基本分页管理的基础上新增以下几个步骤:
- 请求调页(查到页表项时进行判断)
- 页面置换(需要调入页面,但没有空闲内存块时进行)
- 需要修改请求页表中新增的表项
3. 页面置换算法
4. 页面分配策略
相关文章:

操作系统内存管理
内存 内存被设计用来存储数据,以便程序在执行之前能够先被加载到内存中,进而被CPU高效地处理。这一机制有效地缓解了CPU与硬盘之间存在的速度差异和矛盾,确保了数据处理流程的顺畅进行。 一、内存管理 1. 进程运行的基本原理 在深入探讨内…...

数据链路层(Java)(MAC与IP的区别)
以太网协议: "以太⽹" 不是⼀种具体的⽹络, ⽽是⼀种技术标准; 既包含了数据链路层的内容, 也包含了⼀些物理 层的内容. 例如: 规定了⽹络拓扑结构, 访问控制⽅式, 传输速率等; 例如以太⽹中的⽹线必须使⽤双绞线; 传输速率有10M, 100M, 1000M等; 以太…...
图像像素如何排列?是如何存储到diocm里面?读取到内存中是如何存储?
图像像素的排列和存储在DICOM(Digital Imaging and Communications in Medicine,医学数字成像和通信)文件中遵循特定的标准。DICOM 是一种国际标准(ISO 12052),用于处理、存储、打印和传输医学影像信息。 …...

HDR视频技术之七:逆色调映射
HDR 技术近年来发展迅猛,在未来将会成为图像与视频领域的主流。当前 HDR 内容非常短缺,限制了 HDR 视听节目的广泛应用。逆色调映射(Inverse Tone Mapping)应运而生,它是一种用来将 SDR 源信号转换为 HDR 源信号的技术,可以应用于…...
12.10深度学习_经典神经网络_GoogleNet自我理解
为了更清晰地展示 GoogLeNet 中每个卷积层及其相关参数,我们可以将这些信息整理成表格形式。这不仅有助于理解每一层的输入和输出尺寸,还能直观地看到卷积核的数量、大小、步长以及填充方式等关键参数。以下是 GoogLeNet 前几层(包括两个卷积…...
漫谈 Vercel Serverless 函数
我们需要明白什么是 Serverless。顾名思义,Serverless 并不是没有服务器,而是 “不需要你管理服务器”。就像你去超市买东西,不用自己去种菜、养鸡,直接挑选、付款就好。Vercel 的 Serverless 函数也是类似的,它帮你自…...

Nacos系列:Nacos 控制台手册
引言 Nacos是阿里巴巴中间件部门开源的一款用于服务发现和配置管理的产品,Nacos 控制台主要旨在于增强对于服务列表、健康状态管理、服务治理、分布式配置管理等方面的管控能力,以便进一步帮助用户降低管理微服务应用架构的成本。 一、访问 Nacos 控制台…...

react-dnd 拖拽事件与输入框的文本选中冲突
问题描述 当我们使用拖拽库的时候,往往会遇到拖拽的一个元素他的子孙元素有输入框类型的dom节点,当拖拽的事件绑定在该元素身上时候,发现子孙的输入框不能进行文本选中了,会按住鼠标去选中文本的时候会触发拖拽 实际的效果&…...
LeetCode:150. 逆波兰表达式求值
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:150. 逆波兰表达式求值 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表…...

python中向量指的是什么意思
一、向量是什么 在数学中,向量(也称为欧几里得向量、几何向量、矢量),指具有大小(magnitude)和方向的量。它可以形象化地表示为带箭头的线段。箭头所指:代表向量的方向;线段长度&am…...

7.Vue------$refs与$el详解 ------vue知识积累
$refs 与 $el是什么? 作用是什么? ref,$refs,$el ,三者之间的关系是什么? ref (给元素或者子组件注册引用信息) 就像你要给元素设置样式,就需要先给元素设定一个 class 一样,同理,…...

一个很好的直接网站操作的回测框架
1 网址 https://cn.tradingview.com/...

【电子元器件】贴片电阻的故障现象、故障原理和解决方法
本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时,也能帮助其他需要参考的朋友。如有谬误,欢迎大家进行指正。 一、故障现象概要 贴片电阻与其他电子元器件相比,虽然属于比较不容易引发故障的零部件,但是在过载或…...

基于Spring Boot + Vue的摄影师分享交流社区的设计与实现
博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实…...
SpringBoot项目监听端口接受数据(Netty版)
文章目录 前言服务端相关配置核心代码 客户端 前言 前言 环境: JDK:64位 Jdk1.8 SpringBoot:2.1.7.RELEASE Netty:4.1.39.Final 功能: 使用Netty监听端口接受客户端的数据,并发送数据给客户端。 服务端 …...

超标量处理器设计笔记(9) 重命名映射表、超标量处理器重命名中相关性问题
寄存器重命名 重命名映射表基于 SRAM 的重命名映射表 超标量处理器的寄存器重命名解决 RAW 相关性解决 WAW 相关性对写 RAT 进行检查(判断哪个 ARF 写入到 RAT)对写 ROB 进行检查(判断) 特殊指令处理方式 重命名映射表 重命名时…...
如何使用 Python 写入文本文件 ?
在Python编程中,写入文本文件是一项基本且重要的操作。 无论是生成日志文件、配置文件,还是进行数据输出,都需要用到这一技能。 下面,我将详细介绍如何使用Python写入文本文件,并提供一些实际开发中的建议和注意事项…...

07篇(附)--仿射变换矩阵
此篇献给某些 头铁 的小只因们,认真钻研下面的数学式吧 原理示例 首先我们以最简单的一个点的旋转为例子,且以最简单的情况举例,令旋转中心为坐标系中心O(0,0),假设有一点P0(x0,y0)࿰…...

KubeSphere搭建单节点RocketMQ
前提环境: Docker环境 Harbor仓库(可选) 参考官方文档: 《Docker 部署 RocketMQ》 https://rocketmq.apache.org/zh/docs/quickStart/02quickstartWithDocker参考官方文档: 《RocketMQ Dashboard》 https://rocketmq.apache.org/zh/docs/deploymentOperations/04Dashboard/ 声…...
深度学习中损失函数(loss function)介绍
深度学习中损失函数(loss function)介绍 在深度学习的宏伟城堡中,损失函数扮演着国王的角色,它决定了模型训练的方向和目标。损失函数,也被称为代价函数,是衡量模型预测与实际结果之间差异的函数。在深度学习的训练过程中&…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...