Main Content

本页的翻译已过时。点击此处可查看最新英文版本。

解决“内存不足”错误

本主题介绍在 MATLAB® 面临内存不足问题时可以使用的几种策略。MATLAB 是在 64 位操作系统上运行的 64 位应用程序。每当它从操作系统请求的内存段大于可用内存时,它就会返回一个错误消息。

MATLAB 具有内置防护机制,可防止创建过大的数组。默认情况下,MATLAB 可使用 100% 的计算机 RAM(不包括虚拟内存)来为数组分配内存,如果数组超过该阈值,则 MATLAB 返回错误。例如,以下语句尝试创建大小不合理的数组:

A = rand(1e6,1e6);
Error using rand
Requested 1000000x1000000 (7450.6GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a long time and cause
MATLAB to become unresponsive.

More information
有关调整此数组大小限制的信息,请参阅工作区和变量预设项。如果关闭数组大小限制,则 MATLAB 返回另一种错误:

A = rand(1e6,1e6);
Out of memory.

More information

无论您由于何种原因遇到内存限制,都有几种解决方法供您选择,具体取决于您的目标。高效使用内存的策略中讨论的方法可以帮助您优化可用内存,包括:

如果您已在高效使用内存,但问题仍然存在,可以参考本页其余各节提供的解决办法。

利用 tall 数组

使用 tall 数组处理无法放入内存的数据旨在帮助您处理太大而无法放入内存的数据集。MATLAB 一次处理一小块数据,并在后台自动执行所有的数据分块和处理。利用 tall 数组的场合主要有两种:

  1. 如果大型数组可放入内存,但在尝试执行计算时内存不足,则您可以将该数组转换为 tall 数组:

    B = tall(A)
    如果大型数组可放入内存,但这些数组消耗了太多内存而无法在计算过程中容纳数据副本,则您可以使用这种方法进行处理。例如,如果您有 8GB 内存和一个 5GB 矩阵,将该矩阵转换为 tall 数组可让您在不耗尽内存的情况下对矩阵执行计算。请参阅将内存数组转换为 tall 数组中有关此用法的示例。

  2. 如果您有基于文件或文件夹的数据,您可以创建一个 datastore,然后基于该数据存储创建一个 tall 数组:

    ds = datastore('path/to/data.csv');
    tt = tall(ds);
    这种方法可以让您充分利用 MATLAB 中 tall 数组的强大功能:数据可以有任意数量的行,且 MATLAB 不会耗尽内存。由于 datastore 同时支持本地和远程数据位置,因此您处理的数据不需要位于您用于分析这些数据的计算机上。有关详细信息,请参阅处理远程数据

利用多台计算机的内存

如果您有计算机集群,您可以使用 Parallel Computing Toolbox™Distributed Arrays (Parallel Computing Toolbox)利用集群中所有计算机的总内存来执行计算。这使您能够将整个分布式数组作为单个实体来对其执行运算。但是,工作进程仅对分配给它的部分数组执行运算,并视需要在彼此之间自动传输数据。

创建分布式数组与创建 tall 数组非常相似:

ds = datastore('path/to/data.csv');
dt = distributed(ds);

仅加载需要的数据

解决内存问题的另一种方法是仅将大型数据集中解决问题所需要的数据导入到 MATLAB 中。从数据库等源中导入时这通常不是问题,因为您可以显式搜索匹配查询的元素。但这在加载大型简单文本或二进制文件时是个常见问题。

datastore 函数使您能够以增量方式处理大型数据集。此函数适用于使用 tall 数组处理无法放入内存的数据Distributed Arrays (Parallel Computing Toolbox),但您也可以将其用于其他目的。在您需要一次将数据集的一小部分加载到内存中时,数据存储很有帮助。

要创建数据存储,您需要提供文件名,或包含一系列具有相似格式的文件的目录。例如,使用单个文件:

ds = datastore('path/to/file.csv')
或者,使用一个文件夹中的一系列文件:
ds = datastore('path/to/folder/')
您也可以使用通配符 * 选择特定类型的所有文件,如:
ds = datastore('data/*.csv')
数据存储支持多种常见文件格式(表格数据、图像、电子表格等)。有关详细信息,请参阅Select Datastore for File Format or Application

除了数据存储,MATLAB 还提供了其他几个用于加载部分文件的函数,例如 matfile 可用于加载部分 MAT 文件。下表按文件类型总结了部分加载函数。

文件类型部分加载
MAT 文件

通过对使用 matfile 函数创建的对象进行索引来加载部分变量。有关这种用法的示例,请参阅 MAT 文件中的大数据

文本

使用 textscan 函数可通过仅读取选定的列和行来访问大型文本文件的一部分。如果您使用 textscan 指定行数或重复格式数字,MATLAB 会提前计算所需的确切内存量。

二进制

您可以使用低级别二进制文件 I/O 函数(例如 fread)访问具有已知格式的任何文件的一部分。对于未知格式的二进制文件,请尝试通过 memmapfile 函数使用内存映射。

图像、HDF、音频和视频

许多 MATLAB 函数都支持从这些类型的文件中加载数据,使您可以选择读取部分数据。有关详细信息,请参阅支持的导入和导出文件格式中列出的函数参考页。

增加系统交换空间

可供您计算机上的应用程序使用的总内存由物理内存 (RAM) 外加磁盘上的页面文件(即或交换文件)组成。交换文件可能非常大(例如在 64 位 Windows® 上为 512 TB)。操作系统将每个进程的虚拟内存分配给物理内存或交换文件,具体取决于系统和其他进程的需求。增加交换文件的大小可以增加总可用内存,但通常也会导致性能下降。

多数系统都允许您控制您的交换文件的大小。涉及的步骤取决于您的操作系统:

  • Windows 系统 - 使用 Windows 控制面板可更改您系统上虚拟内存分页文件的大小。有关详细信息,请参阅 Windows 帮助。

  • Linux® 系统 - 使用 mkswapswapon 命令更改您的交换空间。有关详细信息,请在 Linux 提示符处键入 man 后跟命令名称。

没有用于直接控制 macOS 系统上的交换空间的接口。

设置 Linux 系统上的进程限制

进程限制是单个进程(或应用程序)可寻址的最大虚拟内存量。您只有在极特殊的情况下才需要设置此预设项,它必须足够大以容纳以下内容:

  • 要处理的所有数据

  • MATLAB 程序文件

  • MATLAB 可执行文件自身

  • 其他状态信息

64 位操作系统支持 8 TB 的进程限制。在 Linux 系统上,查找 ulimit 命令以查看和设置用户限制(包括虚拟内存)。

Linux 系统上禁用 Java VM

在 Linux 系统上,如果您不使用 Java® JVM™ 启动 MATLAB,则可以将可用工作区内存增加大约 400 MB。要在不使用 Java JVM 的情况下启动 MATLAB,请使用命令行选项 -nojvm。此选项还会将最大连续内存块大小增加几乎同样的量。通过增加最大连续内存块,您可以增大矩阵大小上限。

使用 -nojvm 会带来某种损失,您将失去依赖 Java 软件的许多功能,包括整个开发环境。启动 MATLAB 时指定 -nodesktop 选项并不会节省大量内存。

另请参阅

相关主题