数据在内存中的存储
这里博主给大家分享一下博主学习c/c++的时候学习的计算机基础的知识
这里博主建议小白可以先不看这篇文章,等有一定的基础过后再回过来看这篇文章就不会那么迷糊了
博主本人就是这样学的
数据在内存中的存储
单位
内存条是一个非常精密的部件,包含了上亿个电子元器件,它们很小,达到了纳米级别。这些元器件,实际上就是电路;电路的电压会变化,要么是 0V,要么是 5V,只有这两种电压。5V 是通电,用1来表示,0V 是断电,用0来表示。所以,一个元器件有2种状态,0 或者 1(没想到吧内存条竟然是这样的,当时博主也没想到)
一般情况下我们不一个一个的使用元器件,而是将8个元器件看做一个单位,即使表示很小的数,例如 1,也需要8个,也就是 00000001。
一个元器件称为1比特(Bit)或1位,8个元器件称为1字节(Byte),那么16个元器件就是2Byte,32个就是4Byte,
1024Byte,简写为1KB(程序猿经典1024,哈哈)
1024KB,简写为1MB
1024MB,简写为1GB。
以后可别再以为1kb就是1000个字节了哈(作为程序员属实丢不起这个人)
程序的内存分配
在计算机系统中,运行的应用程序的数据都是保存在内存中,不同类型的数据,保存的内存区域不同,包括:
1、栈区[stack]:由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区[heap]:一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式类似于链表。
3、全局区[静态区]:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
4、文字常量区:存放常量字符串。程序结束后由系统释放。
5、程序代码区:存放函数体的二进制代码。
6、寄存器区:用来保存栈顶指针和指令指针(汇编操作)
这里第4 5 6点见的比较少
(一)栈区中的数据
1、应用程序启动后,操作系统会为应用程序在栈区中开辟内存空间,用于存放局部变量以及函数的参数等;
2、iOS主线程栈区大小为1M,MAC主线程栈区大小为8M;
3、栈区中的变量由编译器负责分配和释放;
4、栈区中的数据以“栈”的形式管理的,后进先出(LIFO)
5、访问栈区中变量的效率高,不会出现内存碎片
6、栈区中的变量名(不带*)相当于是指向栈区数据的指针别名,变量名可以简化程序猿的工作。
(二)堆区中的数据
1、由于栈区中的空间有限,iOS的应用程序中,对象都是建立在堆中的
2、堆区包括系统内存和虚拟内存(硬盘缓存),由所有正在运行的应用程序共享使用;
3、堆区中的内存分配由操作系统负责,操作系统使用一个链表统一维护所有已经分配的内存记录
4、由于堆区是由所有应用程序共享的,操作系统以匿名(只记录内存地址和大小,不记录具体类型)的方式记录已经分配的内存区域
5、要访问堆区中的数据,必须通过指针的方式才可以进行,指针的类型决定了访问堆中的数据方式
6、当某一内存区域不再使用时,程序需要通知操作系统回收该内存区域,从而可以保证该内存区域被其他程序再次使用,否则,该区域将永远无法再次分配,这就是“内存泄露”
7、如果某一区域已经被释放,仍然试图访问该区域,会提示“坏内存访问”,这就是“野指针错误”
8、相比较栈区,堆区中的效率要低很多,同时容易出现内存碎片
9、相比较栈区,堆区中的访问方式更加灵活,对象占用的内存也可以更大
运行软件原理
eg.
双击QQ图标,操作系统就会知道你要运行这个软件,它会在硬盘中找到你安装的QQ软件,将数据复制到内存,QQ不是在硬盘中运行的,而是在内存中运行的。(不仅qq是这样的其他所有的软件都是这样的)
因为内存的读写速度比硬盘快很多
读写速度,内存 > 固态硬盘 > 机械硬盘
所以,不管是运行QQ还是编辑Word文档,都是先将硬盘上的数据复制到内存,才能让CPU来处理,这个过程就叫作载入内存。完成这个过程需要一个特殊的程序,这个程序就叫做加载器
CPU直接与内存打交道,它会读取内存中的数据进行处理,并将结果保存到内存。如果需要保存到硬盘,才会将内存中的数据复制到硬盘。
虚拟内存
这里就是说到上面堆区提到的虚拟内存
如果我们运行的程序较多,占用的空间就会超过内存(内存条)容量。
eg.
计算机的内存容量为8G,却运行着10个程序,这10个程序共占用12G的空间,也就意味着需要从硬盘复制 12G 的数据到内存,这显然是不可能的。
但是操作系统,为我们解决了这个问题:当程序运行需要的空间大于内存容量时,会将内存中暂时不用的数据再写回硬盘;需要这些数据时再从硬盘中读取,并将另外一部分不用的数据写入硬盘。这样,硬盘中就会有一部分空间用来存放内存中暂时不用的数据。这一部分空间就叫做虚拟内存
正是因为 虚拟内存 的存在,通过 虚拟内存 可以让程序可以拥有超过系统物理内存大小的可用内存空间。
另外,虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种自己在独享主存的错觉(每个进程拥有一片连续完整的内存空间)。这样会更加有效地管理内存并减少出错)
硬盘的读写速度比内存慢很多,反复交换数据会消耗很多时间,所以如果你的内存太小,会严重影响计算机的运行速度,甚至会出现”卡死“现象,即使CPU强劲,也不会有大的改观
CPU直接从内存中读取数据,处理完成后将结果再写入内存。
所以小伙伴们买电脑要买内存大的,运行就更快
ASCII 编码
收录了 128 个字符,包含了基本的拉丁字母(英文字母)、阿拉伯数字(也就是 1234567890)、标点符号(,.!等)、特殊符号(@#$%^&等)以及一些具有控制功能的字符
GB2312编码和GBK编码,将中文存储到计算机
eg.
GBK就是在保存你的帖子的时候,一个汉字占用两个字节。外国人看会出现乱码,此为我国为自己汉字编码而形成之解决方案。UTF8就是在保存你的帖子的时候,一个汉字占用3个字节。。但是外国人看的话不会乱码。
Unicode字符集,将全世界的文字存储到计算机
Unicode 是一套字符集,而不是一套字符编码
字符集定义了字符和二进制的对应关系,为每个字符分配了唯一的编号。
可以将字符集理解成一个很大的表格,它列出了所有字符和二进制的对应关系,计算机显示文字或者存储文字,就是一个查表的过程。
字符编码规定了如何将字符的编号存储到计算机中。字符编号在存储之前必须要经过转换,在读取时还要再逆向转换一次,使用的这套转换方案就叫做字符编码。
Unicode 可以使用的编码方案有三种,分别是:
1. UTF-8:一种变长的编码方案,使用 1~6 个字节来存储
2. UTF-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储
3. UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变
注意:只有 UTF-8 兼容 ASCII,UTF-32 和 UTF-16 都不兼容 ASCII
本文对于编码部分博主介绍的比较少,如果想深入了解的小伙伴们自行百度