【发布时间】:2015-10-15 17:31:39
【问题描述】:
更新: PowerShell 5 似乎解决了以下错误。错误仍然存在于 3 和 4 中。因此,除非您正在运行 PowerShell 2 或5.
考虑以下代码sn-p:
function Get-DummyData() {
for ($i = 0; $i -lt 10000000; $i++) {
"This is freaking huge!! I'm a ninja! More words, yay!"
}
}
Get-DummyData | Out-Null
这将导致 PowerShell 内存使用量无法控制地增长。在执行了几次Get-DummyData | Out-Null 之后,我看到 PowerShell 内存使用量一直上升到 4 GB。
根据ANTS Memory Profiler,我们在垃圾收集器的终结队列中有很多东西。当我调用[GC]::Collect() 时,内存从 4 GB 变为仅 70 MB。所以严格来说,我们没有内存泄漏。
现在,当我完成一个长期存在的管道操作时,能够致电[GC]::Collect() 对我来说还不够好。我需要在管道操作期间进行垃圾收集。但是,如果我在管道执行时尝试调用 [GC]::Collect()...
function Get-DummyData() {
for ($i = 0; $i -lt 10000000; $i++) {
"This is freaking huge!! I'm a ninja! More words, yay!"
if ($i % 1000000 -eq 0) {
Write-Host "Prompting a garbage collection..."
[GC]::Collect()
}
}
}
Get-DummyData | Out-Null
...问题仍然存在。内存使用量再次无法控制地增长。我尝试了几种变体,例如添加[GC]::WaitForPendingFinalizers()、Start-Sleep -Seconds 10 等。我尝试更改垃圾收集器latency modes 并强制PowerShell 使用server garbage collection 无济于事。我只是无法让垃圾收集器在管道执行时完成它的工作。
这在 PowerShell 2.0 中根本不是问题。值得注意的是,$null = Get-DummyData 似乎也可以在没有内存问题的情况下工作。所以它似乎与管道有关,而不是我们生成大量字符串这一事实。
如何防止我的内存在长管道期间不受控制地增长?
旁注:
我的 Get-DummyData 函数仅用于演示目的。我的实际问题是我无法使用Get-Content 或Import-Csv 在PowerShell 中读取大文件。不,我不将这些文件的内容存储在变量中。我应该是strictly using the pipeline。 Get-Content .\super-huge-file.txt | Out-Null 产生同样的问题。
【问题讨论】:
-
内存耗尽部分听起来像是一个错误。您可以通过使用分配、强制转换或属性枚举避免管道/枚举 1000 万个对象,从而显着减少 CPU 时间
-
我无法用提供的代码 sn-p 重现问题。
-
@RomanKuzmin 你在使用 PowerShell 2.0 吗?
-
在 V4 和 V5 版本 5.0.10240.16384 上执行第二个示例期间,我看到 > 2 GB 的内存使用量。
标签: powershell memory garbage-collection powershell-3.0