今天上朱老师的课又学到了很多新东西
老师对内存的讲解令我茅塞顿开。
加油冲冲冲!
在这里发个笔记记一下自己的学到的东西。
关于内存这个大话题
1.程序运行为什么需要内存?
1.1 计算机程序运行的目的
程序运行目的是为了去运行数据。
计算机程序= 代码+ 数据(经过运行)=结果,程序运行是为了得到一定的结果。计算机就是用来计算的,所有的计算机程序其实都是在做计算。计算就是在计算数据。所以计算机程序中很重要的部分就是数据。
从宏观上来理解,代码就是动作,就是加工数据的动作;数据就是数字,就是被代码加工的东西。
那么可以得出结论,程序运行的目的不外乎两个:结果、过程
用函数来类比:函数的形参就是待加工的数据(函数内还需要一些临时数据,就是局部变量)。函数本体就是代码,函数的返回值就是结果,
函数体的执行过程就是过程。
int add(int a, int b)
{
return a + b;
//这个函数执行是为了得到结果
}
void add (int a, int b)
{
int c;
c = a + b;
printf("c = %d\n",c);
//这个函数执行重在过程(重在过程中的printf),返回值不重要
}
int add(int a, int b)
{
int c;
printf("c = %d \n",c);
return c;
} //这个函数又重结果又重过程
1.2 计算机程序运行过程
计算机程序的运行过程,其实就是程序中很多个函数相继运行的过程。程序是由很多个函数组成的,程序的本质就是函数,函数的本质是加工数据的动作。
1.3 冯诺依曼结构和哈佛结构
冯诺依曼结构:数据和代码放在一起
哈佛结构:数据和代码分开放
什么是代码? 函数
什么是数据? 全局变量、局部变量
在S5PV210中运行的linux系统上,运行应用程序时,这时候所有应用程序的代码和数据都在DRAM,所以这种结构就是冯诺依曼结构;在单片机中,我们把程序代码烧写到Flash(Norflash)中,然后程序在Flash中原地运行,程序中所涉及到的数据(全局变量、局部变量)不能放在Flash(只读)中,必须放在RAM(SRAM)中。这种结构就叫哈佛结构。
1.4 动态内存DRAM和静态内存SRAM
DRAM 只能将数据保存很短的时间。为了保持数据,DRAM使用电容存储,所以必须隔一段时间refresh一次,如果存储单元没有被刷新,存储的信息就会丢失(需要初始化)
SRAM 不需要刷新电路就可以保存它内部存储的数据(不需要初始化)
1.5 为什么需要内存?
内存是用来存储可变数据的,数据在程序中表现为全局变量、局部变量等(在gcc中,常量也是存储在内存中的;大部分单片机中常量是存储在Flash中,也就是在代码段),对我们写程序来说非常重要,对程序运行更是本质相关。
所以内存对程序来说几乎是本质需求,越简单的程序需要越少的内存,越庞大复杂的程序需要更多的内存。内存管理是我们写程序时很重要的话题,很多编程的关键其实就是为了内存,譬如说数据结构(数据结构就是研究如何数据如何组织的)和算法(算法是为了更优秀更有效的来加工数据)。
1.6 如何管理内存(无OS时,有OS时)
有OS时:操作系统掌握所有的硬件内存,内存很大,所以操作系统把内存分成一个一个的页面(其实就是一块,一般是4kb),然后以页面为单位来管理。页面内用更细小的方式来以字节为单位来管理,非常复杂。对于使用操作系统的人来说,不需要了解这些细节。操作系统给我们提供了内存管理的一些接口,我们只需要用API即可管理内存。譬如在C语言使用malloc free这些接口来管理内存。
无OS时:裸机程序中程序需要直接操作内存,编程者需要自己计算内存的使用和安排。如果不小心把内存用错了,错误结果自己承担。
再从语言角度来讲:
汇编:根本没有任何内存管理,全靠程序员自己,汇编中操作内存直接使用内存地址(譬如0xd0020010),非常麻烦;
C语言:编译器帮我们管理直接内存地址,通过编译器提供的变量名等来访问内存,如需大量内存,可以通过API(malloc free)来访问系统内存。
c++:c++对内存的使用进一步封装。我们可以用new来创建对象(其实就是为对象分布内存),然后使用完了delete删除对象(其实就是已释放内存),但是c++中的内存管理还是需要程序员自己来做。如果new了忘记delete,就会造成这个对象占用的内存不能释放,这就是内存