从头梳理内存与内存管理
对于大多数开发者,特别是 C, Objective-C, Swift 等相关的开发者来说,已经很了解如何避免内存泄漏,解决循环引用等问题。但如果继续深入讨论为何会需要手动管理内存,为何内存泄漏仅在特定场景下产生,如何尽可能减少内存开销等问题时,能回答很清楚的人就相对较少了。
所以还是有必要从头梳理一下关于内存的基本知识与概念了,如果我们掌握了这些知识,相信很多问题就会迎刃而解了。
- 位 :( bit ) 是电子计算机中最小的数据单位。每一位的状态只能是0或1。
- 字节:1 Byte = 8 bit ,是内存基本的计量单位,
- 字:"字" 由若干个字节构成,字的位数叫做字长,不同档次的机器有不同的字长。
- KB :1KB = 1024 Byte。 也就是1024个字节。
- MB : 1MB = 1024 KB。类似的还有GB、TB。
- 内存编址:计算机中的内存按字节编址,每个地址的存储单元可以存放一个字节(8个bit)的数据,CPU通过内存地址获取指令和数据,并不关心这个地址所代表的空间具体在什么位置、怎么分布,因为硬件的设计保证一个地址对应着一个固定的空间,所以说:内存地址和地址指向的空间共同构成了一个内存单元。
- 内存地址:内存地址通常用十六进制的数据表示,例如通常在C或者Objective-C中输出一个变量的地址可能为:0x7fff5fbff79c,这就是一个用十六进制的数表示的地址。
下图的整数100在三种进制中的表示:
从硬件的角度来说,它是重要的部件之一.
也是硬盘与 CPU 之间沟通的桥梁。所有的应用程序运行时都会放入内存,然后交由 CPU 进行计算执行。CPU 能通过寻址找到内存对应的数据。
严格意义上讲,内存不仅仅是我们经常所指的内存条。寄存器(Register)、缓存(Cache) 都属于内存的一种。
所以内存一般分为 RAM(main memory), SRAM(cache), Register。
寄存器是 CPU 的组成部分,因为在CPU内,在设计上和CPU同频,所以CPU对其读写速度是最快的,不需要IO传输。
部分缓存的设计也基本保持了与 CPU 同频,所以速度相对内存也是比较快。
理论上讲,缓存和寄存器是一样快的。不过因为缓存里面的东西不一定就是需要的,如果不存在就要一级一级往下找,直到内存。因为不同的缓存 或内存时钟频率不一样,所以CPU在查找时需要一定的等待时间。
CPU 寻找数据进行运算的流程是:
CPU -> Register -> L1 Cache -> L2 Cache -> 内存
RAM 内存的主频现在主流是1600左右,单位是MHz,这比CPU的速度要低的多。
所谓多少位一般是指处理器(CPU)的运算能力与寻址能力。
- 1.运算能力
比如32位,一次能处理32位,也就是4个字节的数据(1字节=8位)。而64位处理器则能处理8个字节的数据。
如果我们将总长128位的指令分别按照16位、32位、64位为单位进行编辑的话:旧的16位处理器,比如Intel 80286 CPU需要8个指令,32位的处理器需要4个指令,而64位处理器则只要两个指令。
- 1.寻址能力
除了运算能力之外,与32位处理器相比,64位处理器的优势还体现在系统对内存的控制上。
相比32位的CPU来说,64位CPU最为明显的变化就是增加了8个64位的通用寄存器,内存寻址能力提高到64位。
32位的内存地址空间为2的32次方,即4GB。64位可获得更大的寻址空间,能识别4G以上的内存。
另外,要实现真正意义上的64位计算,光有64位的处理器是不行的,还必须得有64位的操作系统以及64位的应用软件才行,如果应用软件不支持,反而在64位机器上会变慢。
为了处理数据,暂时储存结果,或者做间接寻址等动作,每个处理器都具备一些内建的内存,这些能够在不延迟的状态下存取的内存就称为寄存器。
寄存器是数据处理的重要一环,如果经常使用汇编语言,对它应该会非常熟悉。
IA-32构架提供了16个基本寄存器,这16个基本寄存器可以归纳为如下几类:
- 通用寄存器
- 段寄存器
- 状态和控制寄存器
- 指令寄存器
通用寄存器 32位通用寄存器有八个,
eax, ebx, ecx, edx, esi, edi, ebp, esp