【问题标题】:"OutOfMemoryException" when using Compress-Archive with 60Gb of files将 Compress-Archive 用于 60Gb 文件时出现“OutOfMemoryException”
【发布时间】:2017-04-25 16:18:52
【问题描述】:

我正在尝试使用 Compress-Archive 压缩 IIS 日志文件(总共 60GB),但是我收到了错误:

“抛出了‘System.OutOfMemoryException’类型的异常。”

$exclude = Get-ChildItem -Path . | Sort-Object -Descending | Select-Object -First 1
$ArchiveContents = Get-ChildItem -Path . -Exclude $exclude | Sort-Object -Descending
Compress-Archive -Path $ArchiveContents -DestinationPath .\W3SVC2.zip -Force

我已经将MaxMemoryPerShellMB调整为2048MB并重启了WinRM服务。

命令执行时RAM内存消耗超过6GB。

【问题讨论】:

  • 您是直接在包含文件的服务器上运行代码还是远程运行?
  • 6 GB 超出了您设置为 2 GB 的限制。总是有将命令设置为计划任务的愚蠢解决方法,这样它就不会在远程会话中运行。或者您可以增加 MaxMemoryPerShellMB。或者您可以使用不同的内存密集型进程来压缩,例如 7zip。
  • 你也可以分批压缩成一个大文件。
  • @BenH 我知道 7zip,但是我尽量远离开源工具;除非这是最后的手段。另外感谢您的建议。是否有可能以最少的系统资源(例如 7zip 等工具)使用“compress-archive”cmdlet?

标签: powershell powershell-5.0


【解决方案1】:

按照 Matt 的建议,我建议将其归档到文件集中。比如:

For($i=0;$i -le $ArchiveContents.Count;$i=$i+10){
    Compress-Archive -Path $ArchiveContents[$i..($i+9)] -DestinationPath .\W3SVC2-$i.zip -Force
}

这样您一次只能处理 10 个文件。您可能需要调整文件的数量,具体取决于您拥有的文件数量和它们的大小,即:如果您有 300 个文件,每个文件 200MB,那么一次 10 个文件可能会很好,而如果您有 3000 个文件,20MB每个您可能希望将其增加到 50 甚至 100。

编辑:我刚刚看了,Compress-Archive 支持通过指定 -Update 参数将文件添加到存档。您应该能够执行与上述相同的操作,稍作修改,制作 1 个大型存档。

For($i=0;$i -le $ArchiveContents.Count;$i=$i+10){
    Compress-Archive -Path $ArchiveContents[$i..($i+9)] -DestinationPath .\W3SVC2.zip -Update
}

这应该一次只将 10 个文件添加到目标存档,而不是尝试一次添加所有文件。

【讨论】:

  • 非常感谢您的建议。如果执行时遇到问题,我会及时通知您。我希望将操作简化为 1 个 .zip 文件,因为它简化了恢复过程。您是否知道是否可以限制 powershell 使用“x”内存量来执行代码?
  • 我不知道如何限制它,但我确实更新了我的答案,只使用 1 个存档文件。
  • 您也可以手动触发垃圾回收以在每次迭代时释放内存。
  • @TheMadTechnician 非常感谢先生。我用你的脚本解决了我的问题。
  • 注意-Force-Update开关在不同的参数集中,所以不能同时使用。
【解决方案2】:

以下解决方案提供比 Compress-Archive

更好的性能

创建 OptimalCompression.ps1

Create Windows Optimized Compression
ECHO OFF
ECHO Starting Compressing $args[0] to $args[1]
$source = $args[0]
$destination = $args[1]
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$includeBaseDirectory = $false
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory("$sourcePath","$destinationPath",$compressionLevel,$includeBaseDirectory)
PAUSE

使用所需参数运行命令

C:\> powershell .\OptimalCompress.ps1 c:\YourSourceFolder c:\YourDestinationFile.zip

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 2021-07-11
    • 1970-01-01
    相关资源
    最近更新 更多