Main Content

解决“不记忆”错误

问题

When your code operates on large amounts of data or does not use memory efficiently, MATLAB®可能会因响应不合理的数组大小而产生错误,或者可能用尽内存。MATLAB具有内置的保护防止创建太大的阵列。例如,此代码会导致错误,因为MATLAB无法创建带有请求的元素数量的数组。

a = rand(1e9);
请求的数组超过最大可能的变量大小。

默认情况下,MATLAB最多可以使用计算机的RAM的100%(不包括虚拟内存)来分配数组的内存,并且如果数组大小超过该阈值,则MATLAB会产生错误。例如,此代码尝试创建一个大小超过最大数组大小限制的数组。

b = rand(1E6);
Requested 1000000x1000000 (7450.6GB) array exceeds maximum array size preference (63.7GB). This might cause MATLAB to become unresponsive.

If you turn off the array size limit inMATLAB工作区首选项,试图创建一个不合理的大数组可能会导致MATLAB用尽内存,或者由于内存过多而导致MATLAB甚至您的计算机无响应(即RAM和磁盘之间移动内存页面)。

b = rand(1E6);
记不清。

Possible Solutions

No matter how you run into memory limits, MATLAB provides several solutions depending on your situation and goals. For example, you can improve the way your code uses memory, leverage specialized data structures such as datastores and tall arrays, take advantage of pooled resources within a computing cluster, or make adjustments to your settings and preferences.

笔记

这solutions presented here are specific to MATLAB. To optimize system-wide memory performance, consider adding more physical memory (RAM) to your computer or making adjustments at the operating system level.

不再需要的清除变量

在不再需要时清除变量的习惯。要从内存中清除项目,请使用clear功能。

Before
一个= rand(1e4); disp(max(A,[],"all")b = rand(1E4);
一个= rand(1e4); disp(max(A,[],"all")) clear一个b = rand(1e4);

有关更多信息,请参阅有效利用内存的策略

使用适当的数据存储

MATLAB数据类型的内存需求不同。您可能能够使用适当的数据类型和存储来减少代码使用的内存量。有关本节中有关解决方案的更多信息,请参见万博 尤文图斯有效利用内存的策略

使用适当的数字类。您应该使用的数字类取决于您的预期操作。在Matlab,双倍的是默认数字数据类型,并为大多数计算任务提供足够的精度:

  • 如果要执行复杂的数学(例如线性代数双倍的)或单位(单身的) 格式。类型数单身的与类型数量相比,需要少的内存双倍的,但也以较少的精度表示。

  • If you just need to carry out simple arithmetic and you represent the original data as integers, use the integer classes in MATLAB.

类(数据类型) Bytes Supported Operations
单身的 4 Most math
双倍的 8 一个ll math
逻辑 1 逻辑/条件操作
INT8,UINT8 1 算术和一些简单的功能
INT16,UINT16 2 算术和一些简单的功能
INT32,UINT32 4 算术和一些简单的功能
int64, uint64 8 算术和一些简单的功能

Reduce the Amount of Overhead When Storing Data.创建数字或字符数组时,MATLAB分配了一个存储器块以存储数组数据。MATLAB还将有关数组数据的信息(例如其类和尺寸)存储在一个小的单独的内存块中,称为Aheader。因为简单的数字和字符阵列的开销最少,请尽可能使用它们。仅将其他数据结构用于太复杂而无法存储在简单数组中的数据。

对于结构和单元格数组,MATLAB不仅为阵列创建一个标题,还为结构的每个字段或单元格数组的每个单元格创建标头。因此,存储结构或单元格数组所需的内存量不仅取决于其拥有的数据,还取决于其构造方式。结果,具有许多小元素或结构的细胞阵列,其中包含很少的内容的许多字段的开销很大,应避免。

Before
% S has 15,000 fields (3 fields per array element)为了i = 1:100为了j = 1:50 S(i,j).R = 0;% Each field contains a numeric scalars(i,j).g = 0;s(i,j).b = 0;结尾结尾
% S has 3 fieldss.r =零(100,50);%每个字段都包含一个数字阵列S.G = zeros(100,50); S.B = zeros(100,50);

Make Arrays Sparse When Possible.一个好的做法是使用稀疏存储存储矩阵很少的非零元素。当完整矩阵具有少量的非零元素时,将矩阵转换为稀疏存储通常会改善内存使用情况和代码执行时间。MATLAB具有几个支持稀疏存储的功能。万博1manbetx例如,您可以使用斯皮尔函数以创建稀疏的身份矩阵。

Before
i =眼(1000);
i = speye(1000);

使用适当的MATLAB类导入数据。When reading data from a binary file with弗雷德,,,,a common mistake is to specify only the class of the data in the file and not the class of the data MATLAB uses once it is in the workspace. If you do not specify the class of the data in memory, MATLAB uses双倍的even if you read 8-bit values.

Before
fileid = fopen(“大_file_of_uint8s.bin”,,,,"r");a = fread(fileid,1e3,“ uint8”);
fileid = fopen(“大_file_of_uint8s.bin”,,,,"r");a = fread(fileid,1e3,“ uint8 => uint8”);

避免不必要的数据副本

为了提高内存使用率和执行速度,请确保您的代码不会导致不必要的数据副本。有关本节中有关解决方案的更多信息,请参见万博 尤文图斯避免不必要的数据副本and有效利用内存的策略

避免创建临时阵列。当不需要时,避免创建临时阵列。例如,而不是创建一个零数组作为临时变量,然后将该变量传递给函数,而是使用一个命令执行两个操作。

Before
a =零(1E6,1);as = single(a);
as = zeros(1e6,1,“单身的”);

预列记忆。When you work with large data sets, repeatedly resizing arrays might cause your program to run out of memory. If you expand an array beyond the available contiguous memory of its original location, MATLAB must make a copy of the array and move the copy into a memory block with sufficient space. During this process, two copies of the original array exist in memory. You can improve the memory usage and code execution time by preallocating the maximum amount of space required for the array. For more information, seePreallocation

Before
x = 0;为了k = 2:1000000 x(k)= x(k-1) + 5;结尾
x = zeros(1,1000000);为了k = 2:1000000 x(k)= x(k-1) + 5;结尾

使用嵌套功能通过更少的参数。When calling a function, MATLAB typically makes a temporary copy of the variable in the caller's workspace if the function modifies its value. MATLAB applies various techniques to avoid making unnecessary copies, but avoiding a temporary copy of an input variable is not always possible.

避免函数调用中临时副本的一种方法是使用嵌套功能。嵌套功能共享所有外部功能的工作空间,因此您无需传递函数调用中的变量副本。有关更多信息,请参阅嵌套功能

Load Only as Much Data as You Need

One way to fix memory issues is to import into MATLAB only as much of a large data set as you need for the problem you are trying to solve. Data set size is not usually a problem when importing from sources such as a database, where you can explicitly search for elements matching a query. But it is a common problem with loading large flat text or binary files.

数据存储功能使您可以逐步处理大型数据集。每当您只想一次将数据设置的某些部分加载到存储器中,数据存储都是有用的。

要创建数据存储,请提供包含具有类似格式的文件集合的文件或目录的名称。例如,使用一个文件,使用以下内容。

ds = datastore(“路径/到/file.csv”);
或使用文件夹中的文件集合,使用以下内容。
ds = datastore(“路径/到/文件夹/”);
You also can use the wildcard character*选择特定类型的所有文件。
ds = datastore(“路径/到/*。csv”);
DataStores支万博1manbetx持多种文件格式(表格数据,图像,电子表格等)。有关更多信息,请参阅Select Datastore for File Format or Application

除DataStores外,MATLAB还具有其他几个功能来加载文件的一部分。该表通过其操作的文件类型来汇总功能。

文件类型 部分加载
垫子

通过将索引索引到您创建的对象来加载变量的一部分矩阵功能。有关更多信息,请参阅将变量的部分保存和加载到垫子中

Text

使用textscan通过仅读取选定的列和行来访问大型文本文件的部分。如果指定行的数量或重复格式编号textscan,,,,MATLABcalculates the exact amount of memory required beforehand.

二进制

您可以使用低级二进制文件I/O功能,例如弗雷德,访问具有已知格式的任何文件的部分。对于未知格式的二进制文件,请尝试使用内存映射memmapfile功能。

图像,音频,视频和HDF

许多支持从这些类型的文件加载的MATLAB函数使您可以选择要读取的数万博1manbetx据的部分。有关详细信息,请参见在此中列出的函数参考页面万博1manbetx支持进口和导出的文件格式

Use Tall Arrays

高数组帮助你处理数据集too large to fit in memory. MATLAB works with small blocks of the data at a time, automatically handling all of the data chunking and processing in the background. You can use tall arrays in two primary ways:

  • 如果您有一个适合内存的较大数组,但是当您尝试执行计算时,内存就用完了,则可以将数组铸成高个数。

    t = tall(A);
    这种方法使您可以使用可以适合内存的大型数组,但是在计算过程中,它会消耗太多的内存以允许数据副本。例如,如果您有8 GB的RAM和一个5 GB矩阵,则将矩阵施放到高阵列中,使您可以在矩阵上执行计算,而不会消耗出内存。有关此用法的示例,请参阅

  • 如果您有基于文件或文件夹的数据,则可以创建数据存储,然后在数据存储的顶部创建一个高阵列。

    ds = datastore(“路径/到/file.csv”);t = tall(ds);
    This approach gives you the full power of tall arrays in MATLAB. The data can have any number of rows and MATLAB does not run out of memory. And because数据存储works with both local and remote data locations, the data you work with does not need to be on the computer you use to analyze it. See使用远程数据了解更多信息。

To learn more about tall arrays, see高音数据的高阵列

Use Memory of Multiple Machines

If you have a cluster of computers, you can use distributed arrays (requires Parallel Computing Toolbox™) to perform calculations using the combined memory of all the machines in the cluster. Depending on how your data fits in memory, different ways to partition data among workers of a parallel pool exist. For more information, seeDistributing Arrays to Parallel Workers(并行计算工具箱)

调整设置和偏好

通常,重写代码是提高内存性能的最有效方法。但是,如果您无法更改代码,这些解决方案可能会为其提供所需的内存量。万博 尤文图斯

开始MATLABWithout爪哇Virtual Machine or Decrease the爪哇堆尺寸。如果您在没有Java的情况下启动MATLAB®虚拟机(JVM™)软件或减小Java堆尺寸,您可以增加可用的工作区内存。要启动没有JVM的MATLAB,请使用命令行选项-nojvm。有关如何减小Java堆尺寸的信息,请参阅爪哇Heap Memory Preferences

使用-nojvm受到惩罚,因为您失去了依赖JVM的几个功能,例如桌面工具和图形。从-nodesktop选项不会保存任何大量内存。

一个djust the Array Size Limit.If you face an error stating that the array size exceeds the maximum array size preference, you can adjust this array size limit in MATLAB. For information on adjusting the array size limit, see工作区和可变偏好。仅当您要创建的数组超过当前最大数组大小限制,但不太适合内存时,此解决方案才有帮助。即使关闭数组尺寸的限制,尝试创建一个不合理的大数组可能会导致MATLAB用尽内存,或者由于内存过多而导致MATLAB甚至您的计算机无反应。

也可以看看

|||

Related Topics