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;
	else
		min_brk = mm->end_data;
#else
	min_brk = mm->start_brk;
#endif
	if (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)是内存管理中的一个重要概念,尤其是在虚拟内存管理中。操作系统通过页来管理物理内存和虚拟内存之间的映射,使得每个进程能够独立地使用其虚拟地址空间,而不直接操作物理内存。这种分页管理有助于实现内存保护、内存共享、内存映射文件等机制。

页的基本概念:

  1. 虚拟内存与物理内存

    • 虚拟内存:是操作系统为每个进程提供的虚拟地址空间。每个进程看到的内存地址是连续的,这与实际的物理内存地址无关。
    • 物理内存:是计算机硬件中的实际内存(RAM),其中存储了系统运行时的程序数据和操作系统的内核。
  2. 页的基本定义

    • 页(Page):虚拟内存的基本单位,操作系统将虚拟地址空间划分为大小相同的块,每个块叫做“页”。通常,一页的大小为 4KB(也可以更大,如 2MB 或 1GB),具体大小取决于体系结构(例如,x86 体系结构通常为 4KB)。
    • 页帧(Page Frame):物理内存的基本单位,物理内存被划分为大小相同的块,每个块叫做“页帧”,对应虚拟内存中的“页”。
  3. 页表(Page Table)

    • 页表是操作系统用于将虚拟地址转换为物理地址的结构。它存储了虚拟页到物理页帧的映射信息。每个进程都有自己的页表,操作系统通过页表来实现虚拟内存到物理内存的映射。
    • 页表的结构通常是多级的(如 2 级页表、4 级页表等),以提高映射效率并减少内存消耗。

分页管理的核心概念:

  1. 虚拟地址空间划分
    虚拟内存被划分成多个大小相等的页。每个进程的虚拟内存都由操作系统划分成若干个虚拟页,而每个虚拟页与物理内存中的页帧通过页表建立映射。

  2. 页面映射
    在一个分页系统中,每个虚拟地址空间的页都与物理内存的页帧相对应。操作系统使用页表来记录这种映射关系。

    • 当进程访问虚拟内存时,操作系统会通过查找页表来获取对应的物理内存地址。
    • 如果虚拟页没有映射到物理页帧(即页面不在内存中),操作系统会触发缺页异常(Page Fault),并将数据从磁盘加载到内存。
  3. 页替换
    由于物理内存的有限性,可能会发生内存不足的情况。这时,操作系统需要将某些不常用的虚拟页面交换到磁盘上的交换空间(Swap Space)中,将内存中的页面替换出来以腾出空间。当需要这些被替换的页面时,它们会重新加载回内存。

  4. 大页(Huge Pages)
    对于某些需要大量内存的应用程序(如数据库、高性能计算等),操作系统允许使用大页(如 2MB 或 1GB 页),以减少页表的开销。大页可以减少页表项的数量,提高内存访问效率。

  5. 页对齐
    在虚拟内存系统中,页是按照一定的对齐方式来管理的,通常是 4KB。页对齐确保了虚拟地址空间和物理内存的页边界一致性。

  6. 页面保护与权限
    每个页都有一定的访问权限,这些权限决定了该页面的访问行为:

    • 读权限(Read)
    • 写权限(Write)
    • 执行权限(Execute)

    这些权限通过页表项设置,并在进程访问该页面时由硬件控制。

Linux 中分页的实现:

在 Linux 操作系统中,虚拟内存管理采用了分页机制。具体来说,Linux 中有以下几个关键组件与分页管理密切相关:

  1. 内存管理单元(MMU)

    • MMU 是硬件部分,它负责执行虚拟地址到物理地址的转换。MMU 利用页表来进行地址转换,确保虚拟内存和物理内存的隔离。
  2. 页表(Page Table)

    • 在 Linux 中,页表是用来维护虚拟地址到物理地址映射的结构。每个进程有自己的页表,操作系统会维护内核的页表。页表结构通常是多级的,包括顶级页表、二级页表等。
  3. 进程虚拟地址空间

    • 每个进程拥有自己的虚拟地址空间,Linux 会将进程的虚拟内存划分为多个区段,如代码段、数据段、堆、栈等。每个区段的虚拟内存都有对应的页表条目。
  4. 缺页异常处理(Page Fault Handling)

    • 当进程访问未映射的虚拟内存时,MMU 会触发缺页异常。Linux 内核会处理缺页异常,判断是通过磁盘交换加载数据还是分配新的物理页面来解决问题。
  5. 交换空间(Swap Space)

    • 当物理内存不足时,Linux 会使用交换空间(swap)将一些不常用的页存储到磁盘中,从而腾出内存空间。交换空间的存在允许系统使用更多的内存,尽管这会降低性能。

总结:

  • 是内存管理的基本单位,操作系统将虚拟内存分成多个大小相同的页,并通过页表映射到物理内存的页帧。
  • 分页可以有效地隔离进程的虚拟内存,提供内存保护、共享、以及懒加载等机制。
  • Linux 使用分页机制来管理虚拟内存,硬件的 MMU 和操作系统的页表配合工作来完成虚拟地址到物理地址的转换。

分页和虚拟内存技术使得操作系统能够更高效、安全地管理内存,提高了系统的可伸缩性和稳定性。

六、伙伴算法

伙伴算法(Buddy Allocation System)是一种内存分配算法,主要用于动态内存管理,特别是在操作系统中用来管理物理内存的分配和释放。它通过将内存块分成具有2的幂大小的区域,并通过将相邻的空闲块配对来实现高效的内存分配。

伙伴算法的核心概念:

  1. 内存分配单位

    • 伙伴算法将内存划分为大小为2的幂的块(例如 2KB、4KB、8KB 等)。每个内存块的大小是2的幂,因此,内存块的大小总是是 2, 4, 8, 16, 32, 64 … 等。
  2. 分区

    • 内存被划分为多个固定大小的块(例如 4KB、8KB、16KB),这些块可以根据需要进行分配。当请求内存时,算法会从大块开始寻找能够满足请求的内存块。
  3. 伙伴

    • 内存中的每一块内存有一个“伙伴”,这个伙伴是与该块内存相邻且大小相同的块。如果一个块的内存被分配,另一个块(它的伙伴)会保持空闲状态,直到其伙伴被释放。
  4. 合并与分裂

    • 当一个内存块被请求时,伙伴算法会根据请求的大小找到最小的、适合的空闲块。如果所需的内存块比当前空闲块大,则需要分割一个更大的块,并将其分成两个“伙伴”块。这个过程会一直递归下去,直到找到合适的块为止。
    • 当释放内存时,算法会检查是否有空闲块的伙伴,如果有,则将它们合并成一个更大的块。这个合并过程会递归进行,直到没有更多的伙伴可以合并为止。

伙伴算法的工作原理:

  1. 分配内存

    • 当程序请求分配大小为 size 的内存时,伙伴算法会在空闲内存块中寻找足够大的块。
    • 如果没有一个空闲块的大小与 size 精确匹配,则从更大的块开始分配,直到找到一个合适的块。对于大于请求的空闲块,系统会将其分裂成两个相同大小的伙伴,继续进行分配。
  2. 释放内存

    • 当程序释放一个内存块时,系统会检查它的伙伴是否也空闲。如果伙伴是空闲的,两个伙伴块就会合并成一个更大的块。
    • 合并后的内存块会继续与它的伙伴合并,直到没有更多的伙伴可以合并为止。合并过程是递归进行的,可能会发生多次合并。

伙伴算法的优缺点:

优点:
  1. 快速分配和释放

    • 由于内存块的大小是2的幂,因此可以通过简单的计算快速找到合适的内存块。这使得内存分配和释放的速度比较快。
  2. 避免外部碎片

    • 由于内存块大小的限制(2的幂次),即使内存中出现了一些“空闲”空间,也能够通过合并操作将碎片整理成较大的块,减少外部碎片问题。
  3. 内存合并

    • 伙伴算法能够在释放内存时进行合并操作,将相邻的空闲内存块合并成一个更大的内存块,从而有效地利用了内存资源。
缺点:
  1. 内部碎片

    • 虽然伙伴算法可以避免外部碎片,但由于内存块大小是2的幂次,可能会出现内部碎片问题。即一个块比实际需要的内存大,导致浪费一部分内存。
    • 例如,如果请求的内存大小为 6KB,但最小可分配的块为 8KB,那么分配的内存将比实际需要的多出 2KB。
  2. 固定块大小

    • 由于内存块的大小是2的幂次,无法处理一些非常小的内存请求(例如 1KB 或 3KB),可能导致某些内存的浪费。
  3. 管理复杂度

    • 伙伴算法的合并操作需要一定的管理工作,尤其是在大量的内存块需要管理时。每次分配和释放内存时都需要更新伙伴关系。

伙伴算法的实现:

在实现伙伴算法时,通常使用一个位图(Bitmap)或者链表来管理每个内存块的空闲和占用状态。常见的实现方式如下:

  1. 位图管理

    • 使用一个位图来记录每个内存块的状态,每个位表示一个内存块的状态(空闲或已分配)。对于每个内存块,还会记录它的伙伴的位置。
  2. 链表管理

    • 将每个大小相同的内存块放入一个链表中,并通过合并操作将它们连接在一起。每个内存块都可以存储它的伙伴信息。
  3. 分配策略

    • 当请求内存时,算法会从最大的块开始查找,直到找到能够满足请求的最小块。如果找到了更大的块,则将它分割为两个相同大小的伙伴,直到获得合适的块。
  4. 合并策略

    • 在释放内存时,算法会检查释放的块是否和它的伙伴是相邻的,如果是相邻的并且空闲,则将这两个块合并成一个更大的块,并将新的块插入到链表中。

例子:

假设内存的最小分配块为 16 字节,并且内存总量为 64 字节。在内存管理开始时,内存将被划分为多个 16 字节的块,形成一个空闲块链表。假设用户请求了 24 字节的内存:

  1. 由于请求是 24 字节,而最小块是 16 字节,伙伴算法将选择一个 32 字节的块进行分配。
  2. 如果请求的内存已经分配出去,系统会将剩余的 8 字节(32 - 24)与相邻的伙伴块进行合并,形成一个 16 字节的块。

总结:

伙伴算法是一个高效的内存分配和释放算法,通过将内存块分成 2 的幂大小的块,并通过合并相邻的空闲块来减少外部碎片。尽管它存在一定的内部碎片和管理复杂度,但在许多操作系统和内存管理系统中,它仍然是一种常用的内存分配策略。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025/1/21 学习Vue的第四天

睡觉。 --------------------------------------------------------------------------------------------------------------------------------- 11.Object.defineProperty 1.在我们之前学习JS的时候&#xff0c;普通得定义一个对象与属性。 <!DOCTYPE html> <h…

机器学习10-解读CNN代码Pytorch版

机器学习10-解读CNN代码Pytorch版 我个人是Java程序员&#xff0c;关于Python代码的使用过程中的相关代码事项&#xff0c;在此进行记录 文章目录 机器学习10-解读CNN代码Pytorch版1-核心逻辑脉络2-参考网址3-解读CNN代码Pytorch版本1-MNIST数据集读取2-CNN网络的定义1-无注释版…

python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖

【1】引言 前序学习了使用numpy创建单通道的灰色图像&#xff0c;并对灰色图像的局部进行了颜色更改&#xff0c;相关链接为&#xff1a; python学opencv|读取图像&#xff08;九&#xff09;用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 之后又学习了使用numpy创…

【MySQL篇】使用mysqldump导入报错Unknown collation: ‘utf8mb4_0900_ai_ci‘的问题解决

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;从事IT领域✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(…

WPF2-在xaml为对象的属性赋值

1. AttributeValue方式 1.1. 简单属性赋值1.2. 对象属性赋值 2. 属性标签的方式给属性赋值3. 标签扩展 (Markup Extensions) 3.1. StaticResource3.2. Binding 3.2.1. 普通 Binding3.2.2. ElementName Binding3.2.3. RelativeSource Binding3.2.4. StaticResource Binding (带参…

软考 系统架构设计师系列知识点之面向服务架构设计理论与实践(5)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之面向服务架构设计理论与实践&#xff08;4&#xff09; 所属章节&#xff1a; 第15章. 面向服务架构设计理论与实践 第2节 SOA的发展历史 15.2 SOA的发展历史 15.2.3 SOA的微服务化发展 随着互联网技术的快速发展&a…

ICLR顶会论文学习|DRL-based改进启发式求解方法JSSP

论文名&#xff1a;Deep Reinforcement Learning Guided Improvement Heuristic for Job Shop Scheduling Authors: Cong Zhang, Zhiguang Cao, Wen Song, Yaoxin Wu, Jie Zh… 论文发表致&#xff1a;ICLR 2024 论文链接&#xff1a;https://doi.org/10.48550/arXiv.2211.1…

OpenCV简介、OpenCV安装

OpenCV简介、OpenCV安装 本文目录&#xff1a; 零、时光宝盒 一、OpenCV简介 二、OpenCV图像处理基础知识 三、OpenCV-Python环境安装 2.1、纯python环境下安装OpenCV 2.2、Anaconda管理环境下安装 OpenCV 四、如何用OpenCV 中进行读取展示图像 五、OpenCV读取图像、显…

利用预训练检查点进行序列生成任务

摘要 大型神经模型的无监督预训练最近彻底改变了自然语言处理。通过从公开发布的检查点进行热启动&#xff0c;自然语言处理从业者在多个基准测试中推动了最先进的技术&#xff0c;同时节省了大量的计算时间。到目前为止&#xff0c;重点主要集中在自然语言理解任务上。在本文…

5、原来可以这样理解C语言_数组(5)sizeof 计算数组元素个数

目录 5. sizeof 计算数组元素个数 5. sizeof 计算数组元素个数 在遍历数组的时候&#xff0c;我们经常想知道数组的元素个数&#xff0c;那C语⾔中有办法使⽤程序计算数组元素个数 吗&#xff1f; 答案是有的&#xff0c;可以使⽤sizeof。 sizeof 中C语⾔是⼀个关键字&#xff…

vue中echarts-中国地图,世界地图显示(echarts5.6版本本地导入)

地图去掉南海诸岛右下角的框显示&#xff08;因为显示的不是现在的10段线&#xff09; 资源里面主要是有个改好的中国地图json其他的无所谓&#xff0c;用现有的json也行&#xff0c;主要是为了解决10段线的问题 引入需要注意 import * as echarts from “./echarts”; 目录…

Ubuntu系统更改IP,保姆级教程

原理概述 本篇文章所用工具&#xff1a; Xshell&#xff1a;点击下载 VMware Workstation Pro&#xff1a;点击下载 密钥需要自行搜索所下载的VMware对应版本密钥。 IP 地址 IP 地址&#xff08;Internet Protocol Address&#xff09;是分配给每个连接到计算机网络的设备的…

IO进程----进程

进程 什么是进程 进程和程序的区别 概念&#xff1a; 程序&#xff1a;编译好的可执行文件 存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09; 程序是静态的&#xff0c;没有任何执行的概念 进程&#xff1a;一个独立的可调度的任务 执行一个程序分配资…

使用插件SlideVerify实现滑块验证

作者gitee地址&#xff1a;https://gitee.com/monoplasty/vue-monoplasty-slide-verify 使用步骤&#xff1a; 1、安装插件 npm install --save vue-monoplasty-slide-verify 2、在main.js中进行配置 import SlideVerify from vue-monoplasty-slide-verify; Vue.use(SlideV…

初探——【Linux】程序的翻译与动静态链接

我们所写的C/C程序计算机是看不懂的&#xff0c;它只认识0101这样的机器码。所以我们就需要借助编译器对这些源代码进行翻译&#xff0c;使之成为计算机能够执行的二进制指令。这个过程通常分为几个关键步骤&#xff1a;预处理、编译、汇编和链接。 一.预处理&#xff08;Prep…

亲测有效!如何快速实现 PostgreSQL 数据迁移到 时序数据库TDengine

小T导读&#xff1a;本篇文章是“2024&#xff0c;我想和 TDengine 谈谈”征文活动的优秀投稿之一&#xff0c;作者从数据库运维的角度出发&#xff0c;分享了利用 TDengine Cloud 提供的迁移工具&#xff0c;从 PostgreSQL 数据库到 TDengine 进行数据迁移的完整实践过程。文章…

matlab实现数据极坐标显示

%% % 读取文件数据 filename E:\ProjectWorkspace\866\866data\665hangji.txt;%代码 距离 方位相对正北 时间 地址 横滚角度 TRK importdata(filename); filename1 E:\ProjectWorkspace\866\866data\665dianji.txt;%代码 距离 方位相对正北 时间 地址 横滚角度 PLOT …

Jenkins 启动

废话 这一阵子感觉空虚&#xff0c;心里空捞捞的&#xff0c;总想找点事情做&#xff0c;即使这是一件微小的事情&#xff0c;空余时间除了骑车、打球&#xff0c;偶尔朋友聚会 … 还能干什么呢&#xff1f; 当独自一人时&#xff0c;究竟可以做点什么&#xff0c;填补这空虚…

人工智能之深度学习_[4]-神经网络入门

文章目录 神经网络基础1 神经网络1.1 神经网络概念1.1.1 什么是神经网络1.1.2 如何构建神经网络1.1.3 神经网络内部状态值和激活值 1.2 激活函数1.2.1 网络非线性因素理解1.2.2 常见激活函数1.2.2.1 Sigmoid 激活函数1.2.2.2 Tanh 激活函数1.2.2.3 ReLU 激活函数1.2.2.4 SoftMa…

卸载和安装Git小乌龟、git基本命令

卸载 Git 打开控制面板&#xff1a; 按 Win R 打开运行对话框&#xff0c;输入 control 并按回车键。或直接在功能搜索里搜索“控制面板”。在控制面板中&#xff0c;选择“程序”或“程序和功能”。 查找并卸载 Git&#xff1a; 在程序列表中找到“Git”或“Git for Windows…