1. 课程导入

大家好,我是你们这门课的老朋友。今天咱们聊聊内存——这个看似基础,却贯穿整个系统性能的核心。

很多人觉得内存就是“插在主板上的那几根条子”。嗯,也对,但太浅了。我做了十几年系统优化,见过太多因为不懂内存而翻车的案例。有一次,一个同事写的程序在测试环境跑得飞快,一上生产就卡成PPT。查了半天,原来是内存访问模式把缓存打爆了。从那以后,我就养成了一个习惯:写代码前,先想想数据在内存里是怎么放的。

1.1 内存到底是什么?

说白了,内存就是一块临时存储区域。CPU要处理的数据,得先放到这里,才能被快速读写。

  • 易失性:断电就丢数据。你想想看,电脑一关机,内存里的东西全没了。
  • 随机访问:读地址A和读地址B,速度差不多。不像磁带,得从头卷。
  • 速度介于CPU和磁盘之间:比CPU慢几个数量级,但比磁盘快几个数量级。

核心认知:内存不是“大仓库”,而是“工作台”。你干活时需要的工具,才放到工作台上。不常用的,放回仓库(磁盘)。

1.2 内存的物理结构:DRAM与SRAM

物理上,内存主要分两种:DRAM(动态随机存取存储器)和SRAM(静态随机存取存储器)。你电脑里插的那根内存条,是DRAM。CPU内部的缓存,是SRAM。

特性 DRAM(主存) SRAM(缓存)
存储单元 1个晶体管+1个电容 6个晶体管
速度 慢(几十纳秒) 快(几纳秒)
容量 大(GB级别) 小(MB级别)
成本 低 高
是否需要刷新 是(每64ms刷新一次) 否

避坑指南:我曾经在嵌入式项目里,为了省成本选了DRAM做缓存。结果因为刷新周期太长,数据丢了。记住:DRAM需要定期刷新,否则电容会漏电。实时性要求高的场景,慎用。

1.3 内存与CPU的关系:冯·诺依曼瓶颈

CPU和内存之间,是“主仆关系”。CPU是老板,内存是秘书。老板要数据,秘书得赶紧递过来。但问题是,秘书跑得没老板快。

这就是著名的“冯·诺依曼瓶颈”:CPU处理速度远快于内存访问速度。CPU大部分时间都在等数据,而不是在算数据。

我做过一个性能分析,发现一个数据库查询里,CPU真正干活的时间只占5%,剩下95%都在等内存把数据搬过来。你想想看,这多浪费。

注意:现代CPU通过超标量、乱序执行、分支预测等技术来掩盖内存延迟。但这些技巧不是万能的。一旦发生缓存未命中(Cache Miss),CPU就得停下来等。这就是为什么内存优化如此重要。

1.4 内存的层次结构:从快到慢

计算机的内存不是一层,而是一个金字塔。越往上,速度越快,容量越小,成本越高。越往下,速度越慢,容量越大,成本越低。

内存层次结构金字塔 寄存器 ~1ns, 几百字节 L1 缓存 ~2ns, 32KB-64KB L2 缓存 ~10ns, 256KB-1MB L3 缓存(共享) ~30ns, 8MB-32MB 主存(DRAM) ~100ns, 8GB-512GB 磁盘(SSD/HDD) ~10ms(HDD)~0.1ms(SSD), 几百GB-几TB 速度递减 容量递增 成本递减 越往下越慢

1.5 各层次详解

寄存器

寄存器在CPU内部,是最快的存储。它直接参与运算。你写的 int a = b + c,b和c就在寄存器里。但寄存器数量极少,一般只有几十到几百个。编译器会尽量把常用变量放寄存器里。

经验之谈:我优化过一段图像处理代码,把循环里的临时变量从内存搬到寄存器,性能提升了30%。但别滥用,寄存器不够用反而会 spill 到栈上,得不偿失。

缓存(L1/L2/L3)

缓存是CPU和主存之间的“缓冲地带”。它利用局部性原理:你刚用过的数据,很可能马上再用(时间局部性);你刚用过的数据旁边的数据,很可能马上也要用(空间局部性)。

  • L1缓存:最快,但最小。每个核心独享。
  • L2缓存:稍慢,但更大。每个核心独享或共享。
  • L3缓存:最慢,但最大。所有核心共享。

我记得有一次排查性能问题,发现一个多线程程序在L3缓存上疯狂冲突。因为两个线程频繁写同一个缓存行,导致伪共享(False Sharing)。解决办法很简单:把数据按缓存行对齐,加填充。性能直接翻倍。

主存(DRAM)

主存就是咱们常说的“内存条”。它容量大,但速度慢。CPU访问主存,需要经过内存控制器。现代CPU把内存控制器集成在芯片内部,减少了延迟。

主存还有一个特点:按行和列组织。访问同一行的数据快,换行就慢。这就是为什么内存访问模式很重要。你写代码时,尽量按顺序访问数组,而不是跳来跳去。

注意:主存访问不是均匀的。同一行内的连续访问,比随机访问快10倍以上。这就是行缓冲区(Row Buffer)的功劳。我见过一个数据库,因为查询没走索引,全表扫描时把内存行缓冲区打爆了,性能惨不忍睹。

磁盘(SSD/HDD)

磁盘是持久化存储。断电不丢数据。但速度最慢。HDD靠机械臂寻道,SSD靠闪存颗粒。虽然SSD比HDD快很多,但和内存比,还是差了几个数量级。

磁盘和内存之间,通过页面交换(Paging)来交互。当内存不够时,操作系统会把不常用的内存页换到磁盘上。这就是虚拟内存的机制。

核心认知:磁盘不是内存的替代品,而是后备仓库。频繁的页面交换会导致系统卡顿,这叫“抖动”(Thrashing)。我优化过一个Java应用,就是因为堆内存设置太小,导致JVM不断GC和页面交换,CPU全花在等磁盘上了。

1.6 总结:为什么内存优化要从基础开始?

好了,这一章的内容就这些。你可能会问:知道这些有什么用?

我告诉你:所有性能问题,最终都归结为数据访问问题。你写的每一行代码,最终都会变成CPU对内存的读写。不理解内存的层次结构,你就不知道瓶颈在哪。

举个例子:你写了一个循环,遍历一个二维数组。如果按行遍历,缓存命中率高;按列遍历,缓存命中率低。性能差10倍。这就是内存层次结构在起作用。