Linux内存管理(Linux内存架构,malloc,slab的实现)
文章目录
- 前言
- 一、Linux进程空间内存分配
- 二、malloc的实现机理
- 三、物理内存与虚拟内存
- 1.物理内存
- 2.虚拟内存
- 四、磁盘和物理内存区别
- 五、页
- 页的基本概念:
- 分页管理的核心概念:
- Linux 中分页的实现:
- 总结:
- 六、伙伴算法
- 伙伴算法的核心概念:
- 伙伴算法的工作原理:
- 伙伴算法的优缺点:
- 优点:
- 缺点:
- 伙伴算法的实现:
- 例子:
- 总结:
前言
本篇文章开始讲解Linux的内存管理,深入了解内存管理有助于我们深入Linux底层逻辑,加强对Linux的学习和了解。
一、Linux进程空间内存分配
下面是一个32位的Linux进程空间内存排布具体的情况:
内核空间(1GB):
内核空间是操作系统核心代码和数据的所在区域。这部分空间由操作系统内核独占,用于执行操作系统的任务,如操作系统的调度、内存管理、驱动程序和系统调用等。在内核空间中,所有的内核模块和驱动程序都运行,并可以直接访问硬件资源。
用户空间(3GB):
用户空间是给用户程序运行的区域,其中包含了应用程序的代码、数据和堆栈等。用户空间是被操作系统管理和分配的,用户程序在这个空间中运行,并通过系统调用与内核进行交互。用户空间中的进程无法直接访问内核空间中的数据和功能,而必须通过系统调用接口来请求内核的服务。
在用户空间中,可以进一步细分不同的段:
1.代码段:存储可执行程序的指令,即程序的二进制代码。
2.数据段:存储全局变量和静态变量等数据。
3.堆区:用于动态分配内存,通过调用malloc()、new等函数实现。
4.栈区:用于存储函数调用时的局部变量和函数调用的上下文。
这种地址空间的分配方式可以提供对操作系统和应用程序的良好隔离,确保系统的稳定性和安全性。操作系统内核在内核空间中运行,可以对硬件资源进行直接访问和管理,而用户程序在用户空间中运行,通过系统调用接口与内核进行通信,实现各种操作和功能。
二、malloc的实现机理
当使用malloc函数时会调用到brk系统调用。
brk系统调用用于改变进程的数据段的结束地址,从而调整进程的堆空间大小。当调用malloc函数时,它会向操作系统请求一块指定大小的内存空间。操作系统会检查当前的堆空间大小,并根据需要调整堆的结束地址,以供新的内存分配。
malloc函数会调用brk系统调用来增加堆空间的大小,以适应所需分配的内存大小。如果请求的内存大小超过了当前堆空间的剩余大小,则操作系统会扩展堆空间,使其满足请求。反之,如果请求的内存大小较小,当前剩余的堆空间可能会被重新分割,并返回相应大小的内存块给malloc函数。
调用brk系统调用将会调用到下面的函数:
这个函数的主要作用是根据用户空间的请求调整进程的数据段结束地址,从而动态调整进程的堆空间大小。
SYSCALL_DEFINE1(brk, unsigned long, brk)
{unsigned long retval;unsigned long newbrk, oldbrk;struct mm_struct *mm = current->mm;struct vm_area_struct *next;unsigned long min_brk;bool populate;if (down_write_killable(&mm->mmap_sem))return -EINTR;#ifdef CONFIG_COMPAT_BRK/** CONFIG_COMPAT_BRK can still be overridden by setting* randomize_va_space to 2, which will still cause mm->start_brk* to be arbitrarily shifted*/if (current->brk_randomized)min_brk = mm->start_brk;elsemin_brk = mm->end_data;
#elsemin_brk = mm->start_brk;
#endifif (brk < min_brk)goto out;/** Check against rlimit here. If this check is done later after the test* of oldbrk with newbrk then it can escape the test and let the data* segment grow beyond its set limit the in case where the limit is* not page aligned -Ram Gupta*/if (check_data_rlimit(rlimit(RLIMIT_DATA), brk, mm->start_brk,mm->end_data, mm->start_data))goto out;newbrk = PAGE_ALIGN(brk);oldbrk = PAGE_ALIGN(mm->brk);if (oldbrk == newbrk)goto set_brk;/* Always allow shrinking brk. */if (brk <= mm->brk) {if (!do_munmap(mm, newbrk, oldbrk-newbrk))goto set_brk;goto out;}/* Check against existing mmap mappings. */next = find_vma(mm, oldbrk);if (next && newbrk + PAGE_SIZE > vm_start_gap(next))goto out;/* Ok, looks good - let it rip. */if (do_brk(oldbrk, newbrk-oldbrk) < 0)goto out;set_brk:mm->brk = brk;populate = newbrk > oldbrk && (mm->def_flags & VM_LOCKED) != 0;up_write(&mm->mmap_sem);if (populate)mm_populate(oldbrk, newbrk - oldbrk);return brk;out:retval = mm->brk;up_write(&mm->mmap_sem);return retval;
}
三、物理内存与虚拟内存
1.物理内存
物理内存是指计算机中实际存在的硬件内存。它是由RAM(Random Access Memory,随机存取内存)或其他类似的硬件组成的,用于存储正在执行的程序和数据。物理内存是直接与计算机的中央处理器(CPU)相连,提供快速、随机访问数据的能力。
2.虚拟内存
虚拟内存是操作系统提供的一种抽象概念。它扩展了可用的内存空间,使得程序可以使用比物理内存更大的地址空间。虚拟内存将程序所需的内存分为连续的地址空间块,称为虚拟地址空间。每个程序都有自己的虚拟地址空间,这使得每个程序能够以独立的方式执行,而不会互相干扰。
虚拟内存的工作原理是将部分程序和数据存储在物理内存中,而将不常用的部分保存在磁盘上的交换文件中。当程序需要访问虚拟内存中的某个地址时,操作系统会根据某种映射机制将虚拟地址转换为物理地址。这个过程被称为虚拟内存管理。通过这种方式,系统可以运行更多的程序,即使物理内存有限。
虚拟内存的主要优势之一是提供了更大的地址空间,以支持大型程序和多任务操作系统。它还可以通过将不常用的数据存储在磁盘上来节省物理内存的使用,并提供更好的内存管理和数据保护机制。
总结而言,物理内存是计算机实际的硬件内存,而虚拟内存是通过操作系统提供的抽象层面扩展的内存概念,使得程序能够使用比物理内存更大的地址空间,并提供更好的内存管理和保护机制。
四、磁盘和物理内存区别
物理内存和磁盘是不同的存储介质,它们在计算机系统中扮演不同的角色和功能。物理内存用于临时存储当前正在执行的程序和数据,而磁盘用于长期存储文件和持久性数据。
五、页
在 Linux 操作系统中,“页”(Page)是内存管理中的一个重要概念,尤其是在虚拟内存管理中。操作系统通过页来管理物理内存和虚拟内存之间的映射,使得每个进程能够独立地使用其虚拟地址空间,而不直接操作物理内存。这种分页管理有助于实现内存保护、内存共享、内存映射文件等机制。
页的基本概念:
-
虚拟内存与物理内存:
- 虚拟内存:是操作系统为每个进程提供的虚拟地址空间。每个进程看到的内存地址是连续的,这与实际的物理内存地址无关。
- 物理内存:是计算机硬件中的实际内存(RAM),其中存储了系统运行时的程序数据和操作系统的内核。
-
页的基本定义:
- 页(Page):虚拟内存的基本单位,操作系统将虚拟地址空间划分为大小相同的块,每个块叫做“页”。通常,一页的大小为 4KB(也可以更大,如 2MB 或 1GB),具体大小取决于体系结构(例如,x86 体系结构通常为 4KB)。
- 页帧(Page Frame):物理内存的基本单位,物理内存被划分为大小相同的块,每个块叫做“页帧”,对应虚拟内存中的“页”。
-
页表(Page Table):
- 页表是操作系统用于将虚拟地址转换为物理地址的结构。它存储了虚拟页到物理页帧的映射信息。每个进程都有自己的页表,操作系统通过页表来实现虚拟内存到物理内存的映射。
- 页表的结构通常是多级的(如 2 级页表、4 级页表等),以提高映射效率并减少内存消耗。
分页管理的核心概念:
-
虚拟地址空间划分:
虚拟内存被划分成多个大小相等的页。每个进程的虚拟内存都由操作系统划分成若干个虚拟页,而每个虚拟页与物理内存中的页帧通过页表建立映射。 -
页面映射:
在一个分页系统中,每个虚拟地址空间的页都与物理内存的页帧相对应。操作系统使用页表来记录这种映射关系。- 当进程访问虚拟内存时,操作系统会通过查找页表来获取对应的物理内存地址。
- 如果虚拟页没有映射到物理页帧(即页面不在内存中),操作系统会触发缺页异常(Page Fault),并将数据从磁盘加载到内存。
-
页替换:
由于物理内存的有限性,可能会发生内存不足的情况。这时,操作系统需要将某些不常用的虚拟页面交换到磁盘上的交换空间(Swap Space)中,将内存中的页面替换出来以腾出空间。当需要这些被替换的页面时,它们会重新加载回内存。 -
大页(Huge Pages):
对于某些需要大量内存的应用程序(如数据库、高性能计算等),操作系统允许使用大页(如 2MB 或 1GB 页),以减少页表的开销。大页可以减少页表项的数量,提高内存访问效率。 -
页对齐:
在虚拟内存系统中,页是按照一定的对齐方式来管理的,通常是 4KB。页对齐确保了虚拟地址空间和物理内存的页边界一致性。 -
页面保护与权限:
每个页都有一定的访问权限,这些权限决定了该页面的访问行为:- 读权限(Read)
- 写权限(Write)
- 执行权限(Execute)
这些权限通过页表项设置,并在进程访问该页面时由硬件控制。
Linux 中分页的实现:
在 Linux 操作系统中,虚拟内存管理采用了分页机制。具体来说,Linux 中有以下几个关键组件与分页管理密切相关:
-
内存管理单元(MMU):
- MMU 是硬件部分,它负责执行虚拟地址到物理地址的转换。MMU 利用页表来进行地址转换,确保虚拟内存和物理内存的隔离。
-
页表(Page Table):
- 在 Linux 中,页表是用来维护虚拟地址到物理地址映射的结构。每个进程有自己的页表,操作系统会维护内核的页表。页表结构通常是多级的,包括顶级页表、二级页表等。
-
进程虚拟地址空间:
- 每个进程拥有自己的虚拟地址空间,Linux 会将进程的虚拟内存划分为多个区段,如代码段、数据段、堆、栈等。每个区段的虚拟内存都有对应的页表条目。
-
缺页异常处理(Page Fault Handling):
- 当进程访问未映射的虚拟内存时,MMU 会触发缺页异常。Linux 内核会处理缺页异常,判断是通过磁盘交换加载数据还是分配新的物理页面来解决问题。
-
交换空间(Swap Space):
- 当物理内存不足时,Linux 会使用交换空间(swap)将一些不常用的页存储到磁盘中,从而腾出内存空间。交换空间的存在允许系统使用更多的内存,尽管这会降低性能。
总结:
- 页是内存管理的基本单位,操作系统将虚拟内存分成多个大小相同的页,并通过页表映射到物理内存的页帧。
- 分页可以有效地隔离进程的虚拟内存,提供内存保护、共享、以及懒加载等机制。
- Linux 使用分页机制来管理虚拟内存,硬件的 MMU 和操作系统的页表配合工作来完成虚拟地址到物理地址的转换。
分页和虚拟内存技术使得操作系统能够更高效、安全地管理内存,提高了系统的可伸缩性和稳定性。
六、伙伴算法
伙伴算法(Buddy Allocation System)是一种内存分配算法,主要用于动态内存管理,特别是在操作系统中用来管理物理内存的分配和释放。它通过将内存块分成具有2的幂大小的区域,并通过将相邻的空闲块配对来实现高效的内存分配。
伙伴算法的核心概念:
-
内存分配单位:
- 伙伴算法将内存划分为大小为2的幂的块(例如 2KB、4KB、8KB 等)。每个内存块的大小是2的幂,因此,内存块的大小总是是 2, 4, 8, 16, 32, 64 … 等。
-
分区:
- 内存被划分为多个固定大小的块(例如 4KB、8KB、16KB),这些块可以根据需要进行分配。当请求内存时,算法会从大块开始寻找能够满足请求的内存块。
-
伙伴:
- 内存中的每一块内存有一个“伙伴”,这个伙伴是与该块内存相邻且大小相同的块。如果一个块的内存被分配,另一个块(它的伙伴)会保持空闲状态,直到其伙伴被释放。
-
合并与分裂:
- 当一个内存块被请求时,伙伴算法会根据请求的大小找到最小的、适合的空闲块。如果所需的内存块比当前空闲块大,则需要分割一个更大的块,并将其分成两个“伙伴”块。这个过程会一直递归下去,直到找到合适的块为止。
- 当释放内存时,算法会检查是否有空闲块的伙伴,如果有,则将它们合并成一个更大的块。这个合并过程会递归进行,直到没有更多的伙伴可以合并为止。
伙伴算法的工作原理:
-
分配内存:
- 当程序请求分配大小为
size
的内存时,伙伴算法会在空闲内存块中寻找足够大的块。 - 如果没有一个空闲块的大小与
size
精确匹配,则从更大的块开始分配,直到找到一个合适的块。对于大于请求的空闲块,系统会将其分裂成两个相同大小的伙伴,继续进行分配。
- 当程序请求分配大小为
-
释放内存:
- 当程序释放一个内存块时,系统会检查它的伙伴是否也空闲。如果伙伴是空闲的,两个伙伴块就会合并成一个更大的块。
- 合并后的内存块会继续与它的伙伴合并,直到没有更多的伙伴可以合并为止。合并过程是递归进行的,可能会发生多次合并。
伙伴算法的优缺点:
优点:
-
快速分配和释放:
- 由于内存块的大小是2的幂,因此可以通过简单的计算快速找到合适的内存块。这使得内存分配和释放的速度比较快。
-
避免外部碎片:
- 由于内存块大小的限制(2的幂次),即使内存中出现了一些“空闲”空间,也能够通过合并操作将碎片整理成较大的块,减少外部碎片问题。
-
内存合并:
- 伙伴算法能够在释放内存时进行合并操作,将相邻的空闲内存块合并成一个更大的内存块,从而有效地利用了内存资源。
缺点:
-
内部碎片:
- 虽然伙伴算法可以避免外部碎片,但由于内存块大小是2的幂次,可能会出现内部碎片问题。即一个块比实际需要的内存大,导致浪费一部分内存。
- 例如,如果请求的内存大小为 6KB,但最小可分配的块为 8KB,那么分配的内存将比实际需要的多出 2KB。
-
固定块大小:
- 由于内存块的大小是2的幂次,无法处理一些非常小的内存请求(例如 1KB 或 3KB),可能导致某些内存的浪费。
-
管理复杂度:
- 伙伴算法的合并操作需要一定的管理工作,尤其是在大量的内存块需要管理时。每次分配和释放内存时都需要更新伙伴关系。
伙伴算法的实现:
在实现伙伴算法时,通常使用一个位图(Bitmap)或者链表来管理每个内存块的空闲和占用状态。常见的实现方式如下:
-
位图管理:
- 使用一个位图来记录每个内存块的状态,每个位表示一个内存块的状态(空闲或已分配)。对于每个内存块,还会记录它的伙伴的位置。
-
链表管理:
- 将每个大小相同的内存块放入一个链表中,并通过合并操作将它们连接在一起。每个内存块都可以存储它的伙伴信息。
-
分配策略:
- 当请求内存时,算法会从最大的块开始查找,直到找到能够满足请求的最小块。如果找到了更大的块,则将它分割为两个相同大小的伙伴,直到获得合适的块。
-
合并策略:
- 在释放内存时,算法会检查释放的块是否和它的伙伴是相邻的,如果是相邻的并且空闲,则将这两个块合并成一个更大的块,并将新的块插入到链表中。
例子:
假设内存的最小分配块为 16 字节,并且内存总量为 64 字节。在内存管理开始时,内存将被划分为多个 16 字节的块,形成一个空闲块链表。假设用户请求了 24 字节的内存:
- 由于请求是 24 字节,而最小块是 16 字节,伙伴算法将选择一个 32 字节的块进行分配。
- 如果请求的内存已经分配出去,系统会将剩余的 8 字节(32 - 24)与相邻的伙伴块进行合并,形成一个 16 字节的块。
总结:
伙伴算法是一个高效的内存分配和释放算法,通过将内存块分成 2 的幂大小的块,并通过合并相邻的空闲块来减少外部碎片。尽管它存在一定的内部碎片和管理复杂度,但在许多操作系统和内存管理系统中,它仍然是一种常用的内存分配策略。
相关文章:

Linux内存管理(Linux内存架构,malloc,slab的实现)
文章目录 前言一、Linux进程空间内存分配二、malloc的实现机理三、物理内存与虚拟内存1.物理内存2.虚拟内存 四、磁盘和物理内存区别五、页页的基本概念:分页管理的核心概念:Linux 中分页的实现:总结: 六、伙伴算法伙伴算法的核心…...

【C++】模板(进阶)
本篇我们来介绍更多关于C模板的知识。模板初阶移步至:【C】模板(初阶) 1.非类型模板参数 1.1 非类型模板参数介绍 模板参数可以是类型形参,也可以是非类型形参。类型形参就是我们目前接触到的一些模板参数。 //类型模板参数 …...

Esxi下虚拟机磁盘类型厚置备改精简置备
Esxi虚拟机磁盘类型厚置备改精简置备 一、esxi报错磁盘不足 1.1、虚拟机报错磁盘不足 1.2、虚拟机磁盘类型 VMware vSphere 中有两种主要类型的虚拟硬盘:精简配置磁盘和厚置备磁盘。 厚置备磁盘有两种分配模型:厚置备延迟置零和厚置备置零。 三者比…...
Element使用表单重置如果不使用prop,重置无法生效
文章目录 为什么需要 prop?示例:使用 prop 的正确方式关键点总结 在 element-ui 的 el-form 组件中, prop 属性是与表单验证和表单字段绑定密切相关的,尤其在使用 resetFields() 重置表单数据时。 如果不使用 prop࿰…...

Windows FileZila Server共享电脑文件夹 映射21端口外网连接
我有这样一个使用场景,在外部网络环境下,通过手机便捷地读取存储在电脑上的视频文件。比如在外出旅行、出差,身边没有携带电脑,仅依靠手机设备,就能随时获取电脑里存储的各类视频,无论是学习资料视频、工作…...

MongoDB 备份与恢复综述
目录 一、基本概述 二、逻辑备份 1、全量备份 2、增量备份 3、恢复 三、物理备份 1、cp/tar/fsync 2、WiredTiger 热备份 3、恢复 四、快照备份 一、基本概述 MongoDB 是一种流行的 NoSQL 数据库,它使用文档存储数据,支持丰富的查询语言和索引…...
node.js 文件操作
在 Node.js 中,文件操作主要通过内置的 fs(File System)模块来实现。 1. 读取文件 const fs require("fs");// 异步读取文件fs.readFile("example.txt", "utf8", (err, data) > {if (err) {console.erro…...

python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)图像变换
形态变换 图像处理中的形态学操作是处理图像结构的有效方法。以下是一些常见的形态学操作的介绍及其在 OpenCV 中的实现示例。 1. 腐蚀(Erosion) 腐蚀操作通过消除图像边界来减少图像中的白色区域(前景),使物体的边…...
Spark SQL中的from_json函数详解
Spark SQL中的from_json函数详解 在Spark SQL中,from_json是一个用于解析JSON数据的函数,主要用于将JSON格式的字符串解析为结构化的数据(即StructType或其他Spark SQL数据类型)。这个函数在处理半结构化数据(如JSON日…...
【软件架构】软件的十二种架构简介
软件的十二种架构简介 一、软件的12种架构 1. 单体架构 (Monolithic Architecture)2. 分层架构 (Layered Architecture)3. 事件驱动架构 (Event-Driven Architecture)4. 微服务架构 (Microservices Architecture)5. 服务导向架构 (Service-Oriented Architecture, SOA)6. 客户…...

日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
日历热力图,月度数据可视化图表,vue组件 先看效果👇 在线体验https://www.guetzjb.cn/calanderViewGraph/ 日历图简单划分为近一年时间,开始时间是 上一年的今天,例如2024/01/01 —— 2025/01/01,跨度刚…...
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
在Vue 3中,导航守卫(Navigation Guard)用于拦截路由的变化,可以在用户访问页面前进行检查。结合Axios进行token认证机制时,我们可以通过导航守卫在路由跳转时,检查用户的认证状态,确保用户有有效…...
【爬虫】使用 Scrapy 框架爬取豆瓣电影 Top 250 数据的完整教程
前言 在大数据和网络爬虫领域,Scrapy 是一个功能强大且广泛使用的开源爬虫框架。它能够帮助我们快速地构建爬虫项目,并高效地从各种网站中提取数据。在本篇文章中,我将带大家从零开始使用 Scrapy 框架,构建一个简单的爬虫项目&am…...

一分钟学习数据安全——白盒加密及安当应用
白盒加密作为一种先进的加密技术,在数据安全、通信安全和信息隐私保护等多个关键领域都有应用。这次的一分钟,让您快速了解一下白盒加密的概念,以及安当产品中的白盒加密应用。 一、什么是白盒加密 简单来说,白盒加密是一种特殊…...

composer安装指定php版本, 忽略平台原因导致的报错
windows下 //composer安装指定php版本, 写出完整的php和composer.phar路径 D:\phpstudy_pro\Extensions\php\php8.1.11nts\php.exe D:\phpstudy_pro\Extensions\composer1.8.5\composer.phar install windows下一些扩展不支持, 如下图, 所以本地composer安装组件时可以忽略 …...
Java 前端详解
Java 前端详解 Java 前端开发主要涉及使用 Java 相关技术和框架来创建用户界面和处理用户交互。虽然 Java 原本是后端开发的主力语言,但它也提供了许多前端开发工具和框架。以下是 Java 前端开发的主要内容和技术栈。 一、Java 前端技术栈 Java Swing 和 AWT AWT (…...

鸿蒙安装HAP时提示“code:9568344 error: install parse profile prop check error” 问题现象
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install parse profile prop check error”错误信息。 解决措施 该问题可能是由于应用使用了应用特权,但应用的签名文件发生变化后未将新的签名指纹重新配置到设备的特权管控白名…...
Javaweb之css
css的三种引入方式 1内行式 2.内嵌式 3.外部样式表 内行式和内嵌式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…...
实施工程师:面试基础宝典
一.运维工程师和实施工程师的区别:工作内容不同、职能不同、工作形式不同 1.工作内容不同: 运维工程师要对公司硬件和软件进行维护。 硬件包括:机房、机柜、网线光纤、PDU、服 务器、网络设备、安全设备等。 实施工程师包括常用操作系统、应…...

react install
react 安装 React 是一个用于构建用户界面的 JavaScript 库。以下是安装 React 的步骤: 使用 Create React App Create React App 是一个官方支持的命令行工具,用于快速搭建 React 应用。 安装 Node.js 和 npm 确保你的计算机上安装了 Node.js 和 npm…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...