内存相关知识(新)

基本概念

  • 内存层次结构:内存层次结构是一种层次化的存储设备结构,它包括寄存器、缓存、主存和辅助存储器。每一层次的存储设备都有不同的速度、容量和成本。

  • 内存单元:内存被划分为一系列连续的内存单元,每个单元都有一个唯一的地址。每个内存单元通常存储一个字节的数据。

  • 地址空间:地址空间是由内存单元组成的线性地址范围,用于寻址和访问数据。地址空间可以分为物理地址和逻辑地址。

  • 物理地址:物理地址是内存中实际的硬件地址,用于访问和存储数据。物理地址是由内存控制器和内存映射电路生成的,并用于在内存中定位特定的数据单元。

  • 逻辑地址:逻辑地址是程序或进程使用的地址,它是相对于程序的地址空间而言的。逻辑地址是在程序执行时使用的,而不是实际存在于内存中的地址。

  • 虚拟内存:虚拟内存是一种将物理内存和辅助存储器(如硬盘)结合使用的技术。它允许程序使用比实际可用物理内存更大的地址空间,通过将不常用的数据存储在辅助存储器中,并在需要时进行交换。

  • 内存管理单元(MMU):内存管理单元是一种硬件设备,用于处理逻辑地址和物理地址之间的转换。MMU负责将逻辑地址转换为对应的物理地址,并进行访问控制和内存保护。

  • 内存访问时间:内存访问时间是指从发出内存读/写请求到完成该请求所需的时间。内存访问时间受到内存层次结构、内存技术和访问模式的影响。

内存的数据结构

  • 数组(Array):数组是一种线性数据结构,由相同类型的元素组成,这些元素在内存中连续存储。数组的访问是基于索引的,可以使用索引来快速访问数组中的元素。例如,int[] numbers = {1, 2, 3, 4, 5}。

  • 链表(Linked List):链表是一种动态数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表的节点可以在内存中分散存储,通过指针链接在一起。例如,链表可以是单链表、双链表、循环链表等。

  • 栈(Stack):栈是一种后进先出(LIFO)的数据结构,只能在栈顶进行插入和删除操作。栈的数据存储在内存中的连续区域,插入和删除操作通过调整栈顶指针来实现。例如,函数调用栈是一种常见的栈结构。

  • 队列(Queue):队列是一种先进先出(FIFO)的数据结构,只能在队尾插入元素,在队头删除元素。队列的数据在内存中以线性方式存储,插入和删除操作通过调整队列头尾指针来实现。例如,消息队列是一种常见的队列结构。

  • 树(Tree):树是一种层次结构的数据结构,由节点和边组成。每个节点可以有多个子节点,只有一个根节点。树的节点可以在内存中分散存储,并且通过指针链接在一起。例如,二叉搜索树、堆、红黑树等。

  • 图(Graph):图是一种由节点和边组成的非线性数据结构,每个节点可以与其他节点通过边相连。图的节点和边可以在内存中以不同的方式存储,如邻接矩阵、邻接链表等。

堆与栈

堆(Heap)和栈(Stack)都是内存中用于存储数据的区域

  • 堆(Heap): 堆是用于动态分配内存的一种数据区域。它的主要特点是内存的分配和释放是由程序员手动控制的,以满足程序的需要。在堆中分配的内存可以在程序的任何地方被访问,并且可以在程序的运行期间动态地分配和释放。
    • 生活中的例子:考虑一个公共图书馆,它有一些书架和一个可供读者自由借阅的书籍区域。 图书馆管理员负责管理和分配这些书籍。每个读者在需要时可以向管理员申请一本书,当读者不再需要一本书时,他们可以归还给管理员。在这个例子中,书架就类似于堆,它是一个公共资源,读者可以在任何时候访问它,并根据需要借阅和归还书籍。
  • 栈(Stack): 栈是一种具有后进先出(LIFO)特性的数据结构,用于存储函数调用和局部变量等信息。栈的主要特点是数据的存储和访问是有序的,每次只能在栈顶进行插入和删除操作。栈的内存分配和回收是由编译器和操作系统自动管理的。
    • 生活中的例子:考虑一个餐厅的盘子堆叠,每当服务员端来一份菜时,他们会将盘子放在堆叠的最顶部。当顾客吃完一份菜后,服务员会从最顶部开始依次拿走盘子。这个盘子堆叠就类似于栈,新的盘子只能在顶部添加,而拿走盘子也是从顶部开始。这种后进先出的结构使得盘子的存储和取出都很方便。

虚拟内存

虚拟内存是计算机系统中的一种内存管理技术,它通过将物理内存和磁盘空间结合起来,为程序提供一个似乎比实际可用内存更大的地址空间。虚拟内存的主要目的是提供比物理内存更大的内存空间,并允许多个进程同时运行。

虚拟内存的工作原理如下:

  1. 地址映射:每个进程在运行时都有自己的虚拟地址空间,该空间被划分为固定大小的页面(通常为4KB)。虚拟地址空间中的每个页面与物理内存中的页面相对应。

  2. 分页:虚拟内存将进程的虚拟地址空间划分为多个页面,并将这些页面映射到物理内存中的页面。这种划分和映射是按需进行的,只有当进程需要访问某个页面时,才将其加载到物理内存中。

  3. 页面置换:当物理内存不足时,虚拟内存使用页面置换算法将一部分不常用的页面从物理内存中置换到磁盘上,以便为正在运行的进程提供足够的空间。当进程再次需要访问被置换的页面时,系统会将其从磁盘加载回物理内存。

虚拟内存的优势包括:

  1. 扩展性:虚拟内存允许每个进程具有更大的地址空间,从而支持更大的程序和数据。

  2. 内存隔离:虚拟内存使得每个进程在运行时相互隔离,不会相互干扰。即使某个进程崩溃或出现错误,也不会影响其他进程的正常运行。

  3. 虚拟内存管理:虚拟内存管理系统负责管理内存的分配和释放,使得程序员无需手动管理内存。

  4. 资源共享:虚拟内存允许多个进程共享同一段物理内存,从而提高内存的利用率。

内存溢出与内存泄露

内存溢出

内存溢出是指程序在运行过程中试图使用超出其分配的内存范围的情况

  •  假设有一个程序需要处理一个非常大的数组,但程序为数组分配的内存空间不足以容纳所有的数据。当程序尝试写入超出内存空间边界的数据时,就会发生内存溢出。这可能导致程序崩溃或出现未定义的行为。
    • 一个程序试图将一个有1000个元素的数组写入一个长度为500的内存缓冲区。由于缓冲区大小不足以容纳整个数组,就会发生内存溢出。

内存泄露

内存泄露是指程序在运行过程中分配了内存但未正确释放,导致这些内存资源无法再被使用

  • 假设有一个程序在每次迭代时动态分配一块内存,并将指针存储在一个数据结构中。但在迭代结束后,程序忘记了释放这些动态分配的内存。这样,随着时间的推移,程序使用的内存会不断增加,最终导致内存泄露。
    • 一个程序在每次循环迭代时动态地分配一个对象,并将指针存储在一个链表中。但在链表中删除对象的操作中,程序忘记释放该对象的内存。随着循环的进行,链表中会有越来越多未被释放的对象,导致内存泄露。

堆区

堆区(Heap)是计算机内存中的一部分,用于动态分配和管理内存。在堆区中,程序可以自由地分配和释放内存,不受固定大小或作用域的限制,因此也被称为动态内存。堆区的大小通常比栈区更大。

堆区的特点包括:

  1. 动态分配:堆区允许程序在运行时动态地请求内存空间,这些内存空间在程序运行结束之前会一直保留。

  2. 无序存储:堆区内存中的数据存储是无序的,没有固定的数据结构。每次分配的内存块可能不连续,因此可以在堆区中分配和释放任意大小的内存块。

  3. 手动管理:在大多数编程语言中,堆区的内存需要手动管理,也就是分配内存时需要手动调用分配函数(如malloc、new等),并在使用完后手动释放内存(如free、delete等),否则可能会导致内存泄漏。

堆内存

堆内存(Heap Memory)是指在计算机中用于存储动态分配对象的一块内存区域。在Java虚拟机(JVM)中,堆内存是用于存储运行时创建的对象的地方。

堆内存的特点包括:

  1. 动态分配:堆内存可以在程序运行时动态地分配和释放内存,而不受固定大小或作用域的限制。在JVM中,通过new关键字创建的对象都存储在堆内存中。

  2. 垃圾回收:Java虚拟机通过垃圾回收机制自动管理堆内存中的对象的生命周期。当对象不再被引用时,垃圾回收器会自动回收这些无用的对象,释放其占用的堆内存空间。

  3. 线程共享:堆内存是所有线程共享的,所有线程都可以访问和操作堆内存中的对象。

YGC与FGC(垃圾回收)

YGC

YGC(Young Generation Garbage Collection):YGC是指针对年轻代(Young Generation)进行的垃圾回收操作。在JVM中,堆内存被划分为年轻代和老年代两个区域。年轻代主要包含新创建的对象,通常包括Eden区和两个Survivor区。当年轻代的空间不足时,会触发YGC。

YGC的过程通常包括以下步骤:

  • 对年轻代进行垃圾回收,标记和清除无用的对象。
  • 将存活的对象移动到Survivor区,同时根据对象的年龄进行晋升(Promotion)。
  • 清空年轻代的空间,为新的对象分配内存。

YGC通常是比较快速的,因为只需要处理年轻代的对象,而年轻代的对象生命周期较短。

FGC

FGC(Full Garbage Collection):FGC是指对整个堆内存进行的垃圾回收操作。当年轻代和老年代都没有足够的空间来分配新的对象时,会触发FGC。

FGC的过程通常包括以下步骤:

  • 对整个堆内存进行垃圾回收,标记和清除无用的对象。
  • 对存活的对象进行压缩和整理,以减少碎片化。

FGC通常比较耗时,因为需要处理整个堆内存的对象,并且可能涉及到对象的移动和内存的整理。

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

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

相关文章

初步了解InnoDB存储引擎的架构设计

1. 更新语句在MySQL中是如何执行的? 之前我们已经分析了MySQL架构上的整体设计原理,现在对一条SQL语句从我们的系统层面发送到MySQL中,然后一步一步执行这条SQL的流程,都有了一个整体的了解。 我们已经知道了,MVSQL最…

Springboot 初始化操作

在使用Springboot过程中,或多或少我们会遇到在Springboot启动时要初始化类,或者加载文件之类的一些操作。关于初始化,主要分为两类,一类是在程序启动后的执行初始化操作,另一类是Bean实例化时执行初始化操作&#xff0…

3D Tiles 规范(一概述)

3D Tiles 专为流式传输和渲染大量 3D 地理空间内容而设计,例如摄影测量、3D 建筑、BIM/CAD、实例化要素和点云。它定义了分层数据结构和一组提供可渲染内容的Tile格式。3D Tiles 没有定义内容可视化的明确规则;客户可以根据自己认为合适的方式可视化 3D …

如何理解Vue 3组件的component关键字

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Verilog仿真跨模块调用内部信号的方法

在Verilog仿真时如果需要调用某子模块中的信号在本模块中使用可以使用层次化引用的方法,而不需要在rtl部分用端口引出来。 引用方式:当前例化模块名.子例化模块名.子子例化模块名.参数 将需要的信号引出。 注意是用例化模块名而不是用子模块名&#xff…

【C++】二维数组传参方式

最近刚开始刷剑指offer,刚做到第三题的时候,发现C二维数组的传参方式和C语言略有些不同,所以在这篇博客中,会列出C/C常见的二维数组传参方式。(本方式和代码都是基于vs环境所编写) 一.C语言二维数组传参方式…

CCF区块链论文录用资讯--ICSE 2024

ICSE是CCF A类会议 (软件工程/系统软件/程序设计语言) 其2024录用了13篇区块链论文 Smart Contract and DeFi Security Tools: Do They Meet the Needs of Practitioners? 智能合约和 DeFi 安全工具:它们满足从业者的需求吗? St…

SegAnyGAussians(SAGA)项目配置和运行

GitHub项目地址:Jumpat/SegAnyGAussians: The official implementation of SAGA (Segment Any 3D GAussians) (github.com) 一、项目准备 1、下载原项目的zip包解压 2、下载third_party目录下的两个模块,放到对应目录下 3、下载预训练模型和数据集 数据…

非计算机专业,如何从事研发岗位的建议!

首先,非计算机专业的毕业生通过读研和专门的培训是完全可以进入IT行业的,目前IT行业内也有大量非计算机专业毕业的技术开发(研发)人员,其中有不少人也非常优秀,发展空间同样比较大。 虽然IT行业内整体的人才…

IPFS分布式存储系统

一、 引言 IPFS是InterPlanetary File System的缩写。它是一个分布式的网络传输协议,它可以把文件分成很多小块放到服务器的不同地方,然后用一种特别的方式来寻找和传输这些小块。这样,我们就可以更快、更安全、更抗容错了的存储文件了。 可能…

从小到大输出四个整数(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int a, b, c, d;int t 0;//提示用户&#xff1b;printf("请输入四个整数a b c d&…

python怎么判断整数

isinstance()函数 可以用来判断变量的类型&#xff0c;它返回的是一个布尔值&#xff0c;False or True。 >>>isinstance("123",str) >>>Flase >>>isinstance(123,int) >>>True >>>isinstance({123},list) >>&g…

【大数据】分布式文件系统HDFS

目录 1.什么是分布式文件系统 2.HDFS的特点 3.HDFS的核心概念 4.HDFS的体系结构 5.HDFS的配置建议 6.HDFS的局限性 7.HDFS的存储机制 7.1.数据冗余机制 7.2.错误与恢复 8.HDFS数据读写过程 1.什么是分布式文件系统 分布式文件系统是整个大数据技术的基础&#xff0c…

京东AI数字人“采销东哥”首秀观看量破2000万;天工 SkyMusic 音乐大模型开放公测

&#x1f989; AI新闻 &#x1f680; 京东AI数字人“采销东哥”首秀观看量破2000万 摘要&#xff1a;京东AI数字人“采销东哥”由京东云言犀打造&#xff0c;在其直播首秀中亮相并迅速吸引超2000万观看量。尽管“采销东哥”的外形和口音与创始人刘强东相似&#xff0c;但其直…

C语言的OJ判题机设计与实现

1. 接收判题入参 判题需要作答代码、测试输入和期望输出、编译器名称、时空限制。对于支持special judge的还需要传入是否为sj和sj代码。推荐使用消息队列&#xff0c;应对高并发的比赛情况会比较好。 但是消息队列是异步的&#xff0c;我为了快点实现能提交后在当前页面获得判…

量子密钥分发系统的设计与实现(二):光路子系统初步讨论

通过上一篇文章&#xff0c;我们对量子密钥分发系统的基本架构、硬件结构以及密钥分发流程进行了初步的总体介绍&#xff0c;从本文开始&#xff0c;我们就基于系统顶层的架构设计&#xff0c;开始从模块到器件&#xff0c;从硬件到软件开始详细讨论QKD系统的设计与实现。本文主…

双向链表详解

目录 带头双向循环链表带头双向循环链表的实现带头双向循环链表的功能实现创造新节点LTNode* CreateLTNode(LTDataType x)代码 初始化链表LTNode*LTInit(LTNode* phead)代码 打印链表void LTPrint(LTNode* phead)代码 链表尾插void LTPushBack(LTNode* phead, LTDataType x)代码…

C#语法知识之运算符

3、运算符 1、算数运算符 1、赋值符号 //把右侧的值赋给左侧的变量2、算数运算符 _ * / float f 1 / 2f; %3、算数运算符的优先级 //乘除余优先级高于加减 括号可以改变优先级&#xff0c;优先计算括号内的内容4、算数运算符的复合运算 复合运算符是用于自己 自己进行运算…

源码解读——SplitFed: When Federated Learning Meets Split Learning

源码地址 1. 源码概述 源码里一共包含了5个py文件 单机模型&#xff08;Normal_ResNet_HAM10000.py&#xff09;联邦模型&#xff08;FL_ResNet_HAM10000.py&#xff09;本地模拟的SFLV1&#xff08;SFLV1_ResNet_HAM10000.py&#xff09;网络socket下的SFLV2&#xff08;SF…

51单片机入门_江协科技_33~34_OB记录的自学笔记_LED呼吸灯与PWM直流马达调速

33. 直流电机驱动(PWM) 33.1. 直流电机介绍 •直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极&#xff0c;当电极正接时&#xff0c;电机正转&#xff0c;当电极反接时&#xff0c;电机反转 •直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&…