mcpField
M
matlab-optimize-memory

matlab-optimize-memory

github.com/matlab开发1.2k71 次安装1 天前更新
代码仓库

关于 matlab-optimize-memory

matlab-optimize-memory 是一套七步 MATLAB 内存诊断与优化技能,强调先测量和分析,再针对热点调整,并验证结果正确性。

主要功能

  1. 01测量内存使用基线
  2. 02分析内存分配
  3. 03识别常见分配模式
  4. 04针对热点实施优化
  5. 05重新测量并验证正确性
  6. 06汇报内存变化

适用场景

  1. 01排查 MATLAB 内存不足错误
  2. 02降低处理大型数据集的内存需求
  3. 03定位 MATLAB 代码中的分配热点

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-optimize-memory

安装后在 Claude Code 中输入/matlab-optimize-memory确认已加载。

附带文件manifest.yamlreferences/memory-patterns.md

详细介绍

MATLAB 内存优化工作流

用于查找和修复 MATLAB 代码中内存瓶颈的系统化 7 步工作流。

适用场景

  • 用户运行 MATLAB 代码时遇到内存不足错误
  • 用户想减少 MATLAB 程序的内存用量
  • 用户想处理更大的数据集,同时避免内存不足
  • 用户要求分析或测量内存分配

不适用场景

  • 瓶颈在于执行速度,而非内存(使用 matlab-optimize-performance)
  • 内存问题出在无法在 M 代码层面修改的已编译 C/MEX 代码中
  • 内存用量主要由 I/O 缓冲区(内存映射文件、数据库连接)占用

7 步工作流

第 1 步:建立内存基线

在进行更改前测量当前内存用量。

m0 = memory;
targetFunction(inputs);
m1 = memory;
deltaBytes = m1.MemUsedMATLAB - m0.MemUsedMATLAB;
fprintf('Memory delta: %.2f MB\n', deltaBytes / 1e6);

当 memory 报错时(Linux/macOS),使用 whos 获取变量大小,或使用 Java 运行时查看堆内存:

info = whos('result');
fprintf('Variable size: %.2f MB\n', info.bytes / 1e6);
第 2 步:分析内存分配

找出内存分配发生的位置。

profile('-memory', 'on');
for iter = 1:5
    targetFunction(inputs);
end
profile off;
p = profile('info');
ft = p.FunctionTable;
[~, idx] = sort([ft.TotalMemAllocated], 'descend');
for i = 1:min(15, numel(idx))
    f = ft(idx(i));
    fprintf('%-40s %10.2f MB\n', f.FunctionName, f.TotalMemAllocated/1e6);
end

如果 TotalMemAllocated 字段为零,则改用每次函数调用前后的 whos 快照。

需要重点关注的内容:

  • “Allocated” 值高但 “Freed” 值低的函数——内存被保留
  • 多次调用且分配量中等的函数——总量会不断累积
  • Allocated 与 Freed 差距很大的情况——临时数据不断累积
第 3 步:找出优化机会

根据分析结果,确定适用的模式。代码示例请参阅 references/memory-patterns.md。

模式典型降幅查找内容
元胞数组收集 + vertcatO(N²) → O(N)循环中的 [arr; newRow]
使用隐式扩展代替 repmat消除完整副本用于广播的 repmat(A, [1 1 K])
用完后清除变量立即回收内存仅在前期步骤中使用的大型数组
拆分链式表达式减少 1 个峰值临时变量a.*b.*c./d 同时存在
重用变量(原地覆盖)避免分配输出每个步骤都使用单独变量
使用 max/min 代替掩码消除逻辑临时变量x .* (x > 0) 模式
zeros(...,'like',x)消除临时变量使用 0 * x 创建零数组
写时复制共享共享底层内存将同一数组赋值到多个位置
密集 → 稀疏O(N²) → O(N·bw)N > 10000 时使用 zeros(N,N)
第 4 步:实施优化

应用已确定的模式。只关注第 2 步找出的热点,不要到处应用这些模式。

第 5 步:测量优化后的内存用量

使用与第 1 步相同的方法重新测量:

m0 = memory;
optimizedFunction(inputs);
m1 = memory;
deltaOpt = m1.MemUsedMATLAB - m0.MemUsedMATLAB;
reduction = 1 - deltaOpt / deltaBytes;
fprintf('Optimized: %.2f MB (%.0f%% reduction)\n', deltaOpt/1e6, reduction*100);
第 6 步:验证正确性

每项优化都必须产生相同的结果:

original = originalFunction(inputs);
optimized = optimizedFunction(inputs);
maxErr = max(abs(original(:) - optimized(:)));
fprintf('Max error: %.2e\n', maxErr);
assert(maxErr < 1e-10, 'Results differ!');
第 7 步:报告结果

总结内存优化情况,包括基线、优化后的数据、降幅百分比、正确性检查结果和应用的模式。

关键规则

  1. 切勿仅凭阅读源代码就提出优化建议——务必先测量和分析
  2. 验证正确性——内存优化必须产生完全相同的结果
  3. 尽早清除变量——数据不再需要时立即释放内存
  4. 避免扩展数组——预分配或使用元胞数组收集数据
  5. 拆分链式表达式——与链式表达式相比,顺序赋值可降低峰值内存用量
  6. 留意副本——MATLAB 采用写时复制;重用变量以避免重复数据

平台说明

  • Windows: memory 命令会返回完整统计信息(MemUsedMATLAB 等)
  • Linux/macOS: memory 会报错(“not supported on this platform”)。使用 whos 获取变量大小,使用 Java Runtime.getRuntime 查看堆用量,或通过 system('ps ...') 获取操作系统级 RSS
  • profile -memory: 可在所有平台上使用,但自 R2016a 起已不再记录于文档中。若不可用,则使用函数调用前后的 whos 快照。

版权所有 2026 The MathWorks, Inc.

评论

支持 Markdown