【问题标题】:Memory leak in batch for loop?批量for循环内存泄漏?
【发布时间】:2011-06-13 12:40:08
【问题描述】:

我正在编写一个批处理脚本,它遍历目录中的每个文件以查找代码文件并以某种方式修改它们。完成该任务后,我尝试在一个包含大约 6,000 个文件的大目录上运行它。脚本崩溃了大约 40 分钟,我从命令提示符处得到了很多内存不足的错误,在查看任务管理器的同时运行脚本表明我的程序以每次循环迭代大约 1MB 的速度消耗内存。所以很自然地认为我做错了什么,我删掉了我为隔离问题而编写的所有代码。但是后来我得到了一个空文件,除了一个 for 循环,问题仍然存在!

这是我在一个相当大的目录上运行的,就像我说的:

@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set directory=%CD%
for /R "%directory%" %%a in (*.c *.cpp *.h *.idl) do (
    set currentDir=%%~dpa
    pushd !currentDir!
    popd
)

我实际上已经能够将其修剪为:

@echo off
for /R "%CD%" %%a in (*) do echo

问题依然存在。

批处理 for 循环中是否存在内存泄漏或者我只是做错了什么?

我运行的是 Windows XP 32 位 Service Pack 2,尽管我已经测试并确认 Service Pack 3 中仍然存在该问题。

【问题讨论】:

  • pushd 命令之后的 popd 是什么意思?这对我来说没有意义。您将一事无成(只是在 2 个目录之间来回切换)。
  • 我正在模拟我的实际代码的作用。在完整的文件中,push 和 pop 之间有很多东西。
  • 好的,我认为你应该在没有显示代码的地方添加...。
  • 哦,我误读了你问题的那一部分。你把它拿出来了。
  • 我只是试图将代码简化为仍然存在泄漏的最小块。如果您愿意,可以添加 echo !currentDir!在推送和弹出之间。

标签: memory memory-leaks batch-file for-loop


【解决方案1】:

这与其说是一个解决方法(或重写)的答案。我已经运行了你的脚本,我看到了一些内存消耗,其中一些在脚本完成之前不会释放,但是每次迭代我没有得到任何接近 1 MB 的东西。 (就像@aphoria 我可以在 c: 的根目录上运行脚本,在 XP SP3 和 Vista 上没有问题。)

我建议您关闭脚本不需要的任何进程,并一次在一个子目录中运行您的脚本。

如果您无法以任何其他方式解决此问题,我建议您尝试在 Powershell 中编写脚本。

【讨论】:

  • 这基本上就是我们正在做的事情。
【解决方案2】:

问题在于 CMD.EXE 和 COMMAND.COM 为使用预留了特定数量的内存。一般在使用批处理文件进行大量处理时,希望增加脚本可以使用的内存工作量。

根据您运行的操作系统环境,您可以执行以下操作:

WINDOWS NT/2000/XP: 你可以改变 COMMAND.COM 环境内存与 /e 开关,例如:

command.com /e:2048 /c BatchFile.BAT

将在 shell 中运行 BatchFile.BAT 2048 字节环境内存。


WINDOWS 95/98/ME:您可以更改 在 a 中分配的环境内存 特定的 MS-DOS 窗口或在 特定批处理文件的快捷方式。 打开属性对话框 (右键单击快捷方式或桌面 图标,然后单击属性)。 单击内存选项卡。使用初始 环境下拉框设置一个 大小足以容纳您的变量, 说 2048 字节(或更多,如果你愿意的话)。

为了安全起见,我也会增加您的磁盘内存使用量。

【讨论】:

    【解决方案3】:

    似乎for /R 占用了内部文件列表的内存。如果从驱动器根目录运行,它会显示内存消耗,因为驱动器根目录基本上有很多递归文件。

    这个显示出更大的消耗:

    @echo off
    
    call :OUT_OF_MEMORY ^^
    exit /b
    
    :OUT_OF_MEMORY
    call set __DUMMY=%%1
    

    使用风险自负,它可能是不可阻挡的。 :)

    PS:在 Windows 7 上重现

    【讨论】:

      猜你喜欢
      • 2017-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-13
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2014-05-17
      相关资源
      最近更新 更多