1

我正在尝试跨合理的数据集进行处理,并尝试在 powershell 7.x 中使用 Foreach-Object -Parallel。

每次我跑步时,我发现我的内存不足似乎每 1000 个对象大约 1 gig,我现在已经提炼成以下代码。(这除了创建然后销毁4000次运行之外什么都不做)

$a = new-object object[] 4000
$a | ForEach-Object -ThrottleLimit 40 -Parallel {
  #Code to do something in here.
}

如果您将 $a 的值更改为 1000,则将消耗大约 1 gig 的内存,将 $a 设置为 2000 然后 2 gig 的内存等。油门限制不会仅更改 CPU 线程数消耗的内存量.

当您想要处理脚本块的次数变大时,这会导致问题。在我的示例中,我需要使用脚本块中的代码处理 20,000 台计算机。运行该代码时,脚本消耗了 16+ gig 并导致分页。

任何人都可以确认他们是否看到相同的问题或者是否有已知的解决方法。

4

1 回答 1

1

感谢 Mathias R. Jessen,他确认这仍然是一个问题和一个建议。将过程分解到现在只处理有限数量的机器以限制内存使用。


$ObjectsToProcess = (1..4102)
$Batch = 0
$BatchSize = 100
do {
    # Create an arrary with limited number of objects in it for memory management
    $ObjectsProcessing = [System.Collections.Generic.List[string]]::new()
    for ($i = $Batch; (($i -lt $Batch + $BatchSize) -and ($i -lt $ObjectsToProcess.count)); $i++) {
        $ObjectsProcessing.add($ObjectsToProcess[$i])
    }

    $ObjectsProcessing | ForEach-Object -ThrottleLimit 40 -Parallel {
        $_
        # Main script in this block now.
    }
    [gc]::Collect() # garbage collection to recover memory
    
    $Batch = $Batch + $BatchSize
} while ($Batch -lt $ObjectsToProcess.count)

这将允许同时处理多达 $BatchSize 的机器,同时机器的数量由 ThrottleLimit 控制。内存消耗可以通过 $BatchSize 来控制。

现在处理 4102 个对象的内存现在从未超过 200 Meg 与以前的 4 Gig。

于 2020-08-26T12:32:43.347 回答