内存是如何工作的

一、什么是内存

从外观上辨识,它就是内存条;从硬件上讲,它叫RAM,翻译过来叫随机存储器。英文全称:Random Access Memory。它也叫主存,是与CPU直接交换数据的内部存储器。其特点是读写速度快,不是一般的快,是我们想像不到的快。

我们可以把内存想像成小时候写作文的本子,只不过,内存的每一行数据都有一个唯一的地址。所以从软件上讲,内存被操作系统管理,根据地址进行寻址和读写数据。对于程序而言,内存是一个逻辑上连续的空间,装载着运行时的程序和数据。为什么说是逻辑上呢,因为有的电脑从物理上看,它可能有两根或以上的内存条,它们都插在主板上,由操作系统将所有的内存条的地址统计进行“登记”,所以,很可能某个程序的一部分存在第一根内存条上,另一部分存在第二根内存条上。但是我们是感知不到的。

内存一般按照字节来编址,从 0 开始,也就是说,地址 0 代表第一个字节,地址 1 代表第二个字节,4GB 的内存,有 210^32 个字节,最大的地址就是 210^32 - 1,用十六进制表示就是 0xFFFFFFFF,这也是为什么 32 位的操作系统,最大支持 4GB 物理内存的原因,而64位操作系统理论上的寻址空间为2的64次方bit,转化单位为2147483648GB,这只是理论值,目前64位windows系统最大只支持128G。

我们可以把内存看成是一家酒店,地址号代表了房间号,每个房间只能住一个人(一个字节),因为内存被设计成单间。如果要住两个人,那只能开两间房。操作系统是酒店的前台小姐姐,负责房间管理工作。她会知道酒店哪些房间已订或空闲,但是她也是酒店的一员,所以,她也要占用房间,至于占用多少房间,取绝于前台小姐姐这个部门的人数。比如早期的WinXp系统就比较小,启动后所占内存500M-1G,到了如今的WIN11系统,原本16G的内存只剩下80%可用,起码要占用2G的内存空间。行政机构真是越来越臃肿!
在这里插入图片描述

程序员的本质工作是什么?

找到前台小姐姐订房,然后将数据和指令安排入住到房间里(这一过程其实是酒店管理人员负责,程序员不用管),操作系统会执行这些指令去处理数据,待处理结束,再将处理好的数据永久保存到外存或输入到其它地方(比如打印出来)。这里会涉及到退房,像C和C++语言,需要程序员来退房,像C#语言则不需要,因为,实际上程序员委托了一家代理商(CLR公共语言运行时)来做开房和退房的工作。

然而在实际程序运行时,有可能出现房间已满无法开房的状态,这个时候可以申请超出物理大小的内存 ,这是因为操作系统提供的其实是虚拟内存(把隔壁的仓库拿出一部分临时改造成酒店的房间),很大一部分申请到的内存,只是建立了映射关系,并没有落到 RAM 里,也有可能一部分内存被交换到了磁盘的 swap 区里。

二、内存装入

不管是操作系统,还是应用程序,它们都存储在硬盘(外存)里面。当我们启动计算机时,首先会点亮主板电源,进而加载并启动主板上的输入输出引导系统(俗称BIOS),这个引导系统会找到硬盘上的操作系统,然后加载操作系统,这个过程实际上是将硬件上的操作系统程序读入到内存。待操作系统完全启动后,将接管对硬件的管理,包括内存的管理。这时,一个16G的内存区域,除了操作系统本身占用了一部分,剩下的区域就等待其它软件和数据去使用。

而程序员要作的,就是开发软件,从操作系统那里申请内存空间,用来存放软件要处理的数据。至于应用软件本身会占据多少内存,如何分配和装入,这一切都交由操作系统来处理。

程序员如何从操作系统哪里申请内存

这一点十分简单,C#有多种数据类型,每种数据类型所占的内存空间大小是不同的,我们会按需申请,绝不浪费,而申请内存的工作其实是交给C#的“运行时”去完成的,我们只需要告诉它一声就行了。即通过new关键词来告诉运行时帮我们开辟内存空间。
在C语言和C++语言中,程序员需要自己主动向操作系统申请空间,待使用完后,再主动销毁,将借来的内存还给操作系统。但是,由于在操作系统和C#之间还存在一个叫CLR运行时的框架,所以,C#程序员在申请内存空间时,其实并不是直接向操作系统申请,而是由CLR运行时在帮助我们完成这一操作。所以,我们申请了内存空间后并不需要还给操作系统,只要这段内存空间不再使用,CLR运行时会帮我们还给操作系统的(即CLR的垃圾回收器支持自动内存管理)。哈,多么人性化的操作!

凡是都有利有弊。CLR的垃圾回收器有时候并不会及时回收内存,而程序员开发出来的软件,因某些业务要不断的申请新的内存空间,总有一刻,内存会被申请完,导致内存不足,程序崩溃。所以,了解内存的结构和正确使用内存,对于立志成为一名高级程序员而言,尤为重要。

C#里面也有及时回收内存的指令,特别是我们申请了超大的连续内存空间,在使用完后,最好及时告诉CLR的垃圾回收器,有借有还,再借不难。
本文原发布于:WPF中文网 wpfsoft.com
——重庆教主 2023年11月30日

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

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

相关文章

JSX语法

文章目录 1.JSX是什么2.JSX书写规范3.JSX中显示数据4.添加样式隔离作用域 5.条件渲染6.列表渲染7.响应事件8.更新页面 1.JSX是什么 JSX是一种JavaScript的语法扩展用于描述页面,并且可以和JavaScript融合在一起不同于Vue的模板语法,没有Vue中的一些指令(v-if,v-show,v-for)在r…

SpringBoot嵌入式容器(自动配置原理、自定义嵌入式容器)

目录 1. 自动配置原理2. 自定义嵌入式容器3. 最佳实践 Servlet容器:管理、运行Servlet组件(Servlet、Filter、Listener)的环境,一般指服务器 1. 自动配置原理 SpringBoot默认嵌入Tomcat作为Servlet容器自动配置类是ServletWebSer…

抽象类与接口

抽象类: 父类某些方法需要声明,但又不确定如何实现,可将其声明抽象方法, 【抽象类主要是为了防止创建父类对象】 抽象类与抽象方法 抽象方法没有方法体 类中有抽象方法,类必须声明为抽象类 …

java开发之个微机器人的实现

简要描述: 二次登录 请求URL: http://域名地址/secondLogin 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明wcId…

k8s之Pod常用命令详解、镜像拉取策略(imagePullPolicy)

常用命令 kubectl get pod #查看默认命名空间下所有pod kubectl describe pod podname #获取默认命名空间下POD详情# 如果要查看制定命名空间则使用 -n nsname kubectl get pod -n ns kubectl describe pod podname -n ns# 以YAML格式提供比 kubectl describe pod 更加详细的信…

【每日一题】从二叉搜索树到更大和树

文章目录 Tag题目来源题目解读解题思路方法一:中序遍历的反序方法二:后缀数组 写在最后 Tag 【中序遍历】【二叉树】【2023-12-04】 题目来源 1038. 从二叉搜索树到更大和树 题目解读 在二叉搜索树中,将每一个节点的值替换成树中大于等于该…

DDR详解

DDR也就是常称的内存在一般使用过程中都是透明的,此文从多方面对DDR进行详解。 DDR训练 高可靠性是系统级芯片SoC重要的质量和性能要求之一。SoC的复杂在于各个IP模块都对其产生至关重要的影响。从芯耀辉长期服务客户的经验来看,在客户的SoC设计中&…

根文件系统lib库添加与初步测试

一. 简介 我们在编译 busybox源码时,选择的是动态编译,所以,制作生成的 根文件系统中/bin或 /sbin目录下软件运行时会调用到一些库文件的。库文件就是交叉编译器的库文件。 前面我们编译 busybox源码时,选择动态编译&#xff0…

NPS内网穿透教程

1.简介 nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发,可支持任何tcp、udp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面,内网dns解析等等……),此外还支持内网ht…

【python爬虫】设计自己的爬虫 2. 数据保存封装 mongodb,mysql和elasticsearch

mongodb, mysql和elasticsearch 功能较相似,所以打算用一套接口将它们封装起来 基类StorageBase 如下: class StorageBase:def __init__(self, hostNone, portNone, databaseNone, tableNone, locationNone, accountNone, passwordNone,urlNone):self…

安卓1.0明显是基于linux内核开发的,安卓1.0是不是linux套壳?

安卓1.0明显是基于linux内核开发的,安卓1.0是不是linux套壳? 在开始前我有一些资料,是我根据自己从业十年经验,熬夜搞了几个通宵,精心整理了一份「安卓开发资料从专业入门到高级教程工具包」,点个关注&…

141. 环形链表

141. 环形链表 设置一个fast指针,一个slow指针,fast一次走两步,slow一次走一步。如果fast和slow相遇,则说明有环。反之没相遇则无环。 注意快慢指针的while循环条件是fast.next ! null && fast.next.next ! null /*** …

大数据集群增加数据盘,平衡数据盘HDFS Disk Balancer

大数据集群增加数据盘,平衡数据盘HDFS Disk Balancer 官网:https://hadoop.apache.org/docs/r3.3.6/hadoop-project-dist/hadoop-hdfs/HDFSDiskbalancer.html hdfs diskbalancer -execute /system/diskbalancer/nodename.plan.jsonhdfs diskbalancer -q…

StringJoiner使用详解

关于StringJoiner 1.介绍2.源码2.1 属性2.2 方法 3 举例StringJoiner做法3.1 只含间隔符3.2 含间隔符和前后缀3.3 merge合并两个joiner3.4 stringJoiner.setEmptyValue("xxx");3.5 综合举例length()方法 1.介绍 在JDK1.8之后,提供了一个StringJoiner类用来…

简谈oracle数据库的归档模式

一、oracle数据库归档模式简介 Oracle数据库归档模式是一种数据备份和恢复策略,它允许数据库记录所有数据库的更改操作(包括已提交和未提交的事务)并将其存储在归档日志中。这些归档日志可以用于在数据库发生故障时进行恢复,并提供点时间恢复(PITR)的能力。 在Oracle数…

ruoyi-vue 整合netty实现TCP/IP协议数据接收

支持持续接收数、可发送数据、可多端口连接。 废话少说,直接上代码! 如果写的可以,记得点个赞~ import com.alibaba.fastjson.JSON; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; imp…

PHP 刷新缓存区的问题!

PHP流式输出,在Nginx下可以正常刷新缓存区 , 但是在Apache下会等待循环全部执行完,才会刷新!有怎么解决? header(X-Accel-Buffering: no); // Nginx情况下必须加这一行header(Content-type: text/event-stream);header…

【刷题】【力扣牛客】反转链表的五种方式——Java

文章目录 前言方法一:构造新链表(构造新节点)方法二:构造新链表(不构造新节点)方法三:递归方法四:双指针方法五:遍历总结 力扣题目链接:206. 反转链表 牛客题…

IDEA2023找不到 Allow parallel run

我的idea版本:2023.1.4 第一步:点击Edit Configrations 第二步:点击Modify options 第三步:勾选Allow multiple instances 最后点击Apply应用一下 ok,问题解决!

SSM项目实战-登录验证成功并路由到首页面,Vue3+Vite+Axios+Element-Plus技术

1、util/request.js import axios from "axios";let request axios.create({baseURL: "http://localhost:8080",timeout: 50000 });export default request 2、api/sysUser.js import request from "../util/request.js";export const login (…