一、什么是内存
从外观上辨识,它就是内存条;从硬件上讲,它叫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日