内存使用powershell 7.03 Foreach对象并行



我试图在一个合理的数据集上进行处理,并在powershell 7.x中尝试Foreach Object-Parallel。

每次运行时,我都会发现内存不足。似乎每1000个对象中就有1个,现在我已经提取到以下代码。(这个剂量除了创造然后摧毁4000次外什么都不做(

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

如果你将$a的值更改为1000,大约会消耗1吉的内存,将$a设置为2000,然后再消耗2吉的内存等。节流限制不会改变只消耗CPU线程数的内存量。

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

请任何人确认他们是否看到了相同的问题,或者是否存在已知的问题。

感谢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兆,而以前是4兆。

我遇到了同样的问题。在forEach并行和do循环结束之间使用垃圾收集的建议有所帮助,但在每次do循环迭代时,内存量会继续增加。我的解决方案是将我在forEach并行代码中的所有代码移动到forEach平行代码部分外部和上方的函数中,然后从forEach并联代码内部调用该函数。

将所有forEach并行代码放在forEach平行代码段外部和上方的函数中。

将这行代码放在函数和ForEach对象之间-并行代码。

$YourFunctionNameStg=$function:YourFunctionName:ToString((

将一行代码放在ForEach Object-Parallel代码中。

$function:YourFunctionNameInside=$using:YourFunctionNameStg

在ForEach对象内部-并行代码调用您的函数。

YourFunctionNameInside

最新更新