
在计算机系统中,存储器如同信息的 “仓库”,负责存储程序和数据,是计算机能够正常运行的关键组件。本章将深入探讨存储器的分类、结构、工作原理以及性能优化等内容,通过代码示例和图表辅助,帮助大家更好地理解和掌握相关知识。

存储器可从多个维度进行分类:
存储器的层次结构是为了在成本、速度和容量之间取得平衡,其结构如下图所示:

从寄存器到外存,速度逐渐降低,容量逐渐增大。
主存储器(内存)是 CPU 能直接访问的存储器,用于存放正在运行的程序和数据。它具有存取速度快、容量相对较小、断电后数据丢失等特点。
半导体存储芯片是构成主存的主要部件,常见的有静态随机存取存储器(SRAM)和动态随机存取存储器(DRAM)。SRAM 速度快但成本高、集成度低;DRAM 速度较慢但成本低、集成度高 。
随机存取存储器(RAM)可随时读写数据,断电后数据丢失。下面用 Java 代码模拟一个简单的 RAM 读写操作:
import java.util.HashMap;
import java.util.Map;
// 模拟随机存取存储器(RAM)
public class RandomAccessMemory {
// 使用Map模拟内存存储,键为地址,值为存储的数据
private Map<Integer, Integer> memory = new HashMap<>();
// 写入数据到指定地址
public void write(int address, int data) {
memory.put(address, data);
System.out.println("在地址 " + address + " 写入数据 " + data);
}
// 从指定地址读取数据
public int read(int address) {
return memory.getOrDefault(address, -1);
}
public static void main(String[] args) {
RandomAccessMemory ram = new RandomAccessMemory();
ram.write(100, 10);
int readData = ram.read(100);
System.out.println("从地址 100 读取的数据为: " + readData);
}
}只读存储器(ROM)只能读取数据,不能写入数据,常用于存储计算机启动时的引导程序、BIOS 等重要信息。
存储器与 CPU 的连接需要考虑地址线、数据线和控制线的连接。连接方式示意图如下(Mermaid 流程图):

为了保证数据在存储和传输过程中的准确性,需要进行存储器校验。常见的校验方法有奇偶校验、海明校验等。以下是 Java 实现的奇偶校验示例:
public class ParityCheck {
// 计算奇校验位
public static int calculateOddParity(int data) {
int count = 0;
while (data != 0) {
count += data & 1;
data >>= 1;
}
return (count % 2 == 0) ? 1 : 0;
}
// 计算偶校验位
public static int calculateEvenParity(int data) {
int count = 0;
while (data != 0) {
count += data & 1;
data >>= 1;
}
return (count % 2 == 0) ? 0 : 1;
}
public static void main(String[] args) {
int data = 10;
int oddParity = calculateOddParity(data);
int evenParity = calculateEvenParity(data);
System.out.println("数据 " + data + " 的奇校验位为: " + oddParity);
System.out.println("数据 " + data + " 的偶校验位为: " + evenParity);
}
}
提高访存速度的措施包括采用高速存储芯片、增加 Cache、采用多体交叉存储器等。
高速缓冲存储器(Cache)位于 CPU 和主存之间,用于存放 CPU 近期可能会访问的数据和指令,以提高 CPU 的访存速度。
Cache - 主存地址映射方式有直接映射、全相联映射和组相联映射。以直接映射为例,其原理如下:

Java 代码模拟直接映射地址转换:
public class DirectMapping {
// Cache大小(块数)
private static final int CACHE_SIZE = 16;
// 主存大小(块数)
private static final int MAIN_MEMORY_SIZE = 256;
// 计算Cache块号
public static int calculateCacheBlock(int mainMemoryBlock) {
return mainMemoryBlock % CACHE_SIZE;
}
public static void main(String[] args) {
int mainMemoryBlock = 30;
int cacheBlock = calculateCacheBlock(mainMemoryBlock);
System.out.println("主存块 " + mainMemoryBlock + " 映射到Cache块 " + cacheBlock);
}
}当 Cache 满且需要调入新数据时,需要采用替换策略决定替换哪个 Cache 块。常见的替换策略有先进先出(FIFO)、最近最少使用(LRU)等。下面用 Java 实现简单的 FIFO 替换策略:
import java.util.LinkedList;
import java.util.Queue;
public class FIFOReplacement {
private int cacheSize;
private Queue<Integer> cacheQueue;
public FIFOReplacement(int size) {
cacheSize = size;
cacheQueue = new LinkedList<>();
}
public void add(int block) {
if (cacheQueue.size() == cacheSize) {
cacheQueue.poll();
}
cacheQueue.offer(block);
}
public static void main(String[] args) {
FIFOReplacement fifo = new FIFOReplacement(3);
fifo.add(1);
fifo.add(2);
fifo.add(3);
fifo.add(4);
System.out.println("FIFO替换后的Cache:" + fifo.cacheQueue);
}
}辅助存储器(外存)用于长期存储大量数据和程序,其特点是容量大、速度慢、断电后数据不丢失,如硬盘、光盘、磁带等。
磁记录是利用磁介质的磁化状态来存储信息,常见的记录方式有归零制、不归零制、调相制等。
硬盘存储器是目前最常用的外存设备,由磁盘片、磁头、电机等组成。它通过磁头在旋转的磁盘片上读写数据。
软磁盘存储器曾广泛使用,但由于容量小、速度慢、易损坏等缺点,现已逐渐被淘汰。
磁带存储器采用顺序存取方式,常用于数据备份和大容量数据存储。
循环冗余校验码(CRC)是一种常用的检错码,用于检测数据在存储和传输过程中是否发生错误。以下是 Java 实现 CRC 校验的简单示例:
import java.util.zip.CRC32;
public class CRCCheck {
public static long calculateCRC(String data) {
CRC32 crc32 = new CRC32();
crc32.update(data.getBytes());
return crc32.getValue();
}
public static void main(String[] args) {
String data = "Hello, World!";
long crc = calculateCRC(data);
System.out.println("数据 \"" + data + "\" 的CRC校验值为: " + crc);
}
}
光盘存储器利用激光技术读写数据,常见的有 CD、DVD、蓝光光盘等。
通过对存储器各方面知识的学习和代码实践,相信大家对计算机存储器有了更深入的理解。在实际应用中,存储器的性能和可靠性对计算机系统至关重要,后续还可以进一步探索更复杂的存储器技术和优化方法。