Phi*_*hil 10 memory powershell garbage-collection powershell-3.0
更新: PowerShell 5似乎解决了以下错误.该错误仍然存在于3和4中.因此,除非您运行PowerShell 2或5,否则不要使用管道处理任何大型文件.
请考虑以下代码段:
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
Run Code Online (Sandbox Code Playgroud)
这将导致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
Run Code Online (Sandbox Code Playgroud)
......问题依然存在 内存使用率再次无法控制地增长.我已经试过这几个变化,如添加[GC]::WaitForPendingFinalizers(),Start-Sleep -Seconds 10等我试图改变垃圾收集器的延迟模式,迫使PowerShell来使用服务器垃圾收集无济于事.在管道执行时,我无法让垃圾收集器完成它的工作.
这在PowerShell 2.0中根本不是问题.值得注意的是,$null = Get-DummyData似乎也没有内存问题.所以它似乎与管道有关,而不是我们生成大量字符串的事实.
如何防止我的记忆在长管道中无法控制地增长?
边注:
我的Get-DummyData函数仅用于演示目的.我的现实问题是我无法使用Get-Content或读取PowerShell中的大文件Import-Csv.不,我没有将这些文件的内容存储在变量中.我严格按照我应该使用的管道.Get-Content .\super-huge-file.txt | Out-Null产生同样的问题.
这里有几点需要指出.首先,GC调用在管道中工作.这是一个只调用GC的管道脚本:
1..10 | Foreach {[System.GC]::Collect()}
Run Code Online (Sandbox Code Playgroud)
这是脚本运行期间GC的perfmon图:
但是,仅仅因为您调用GC并不意味着私有内存使用将返回到脚本启动之前的值.GC收集器仅收集不再使用的内存.如果存在对对象的根对引用,则不符合收集(释放)的条件.因此,尽管GC系统通常不会在C/C++意义上泄漏,但它们可能具有可能比应有的更长时间保留对象的内存保持.
在使用内存分析器查看此内容时,似乎大量的多余内存被带有参数绑定信息的字符串副本占用:
这些字符串的根看起来像这样:
我想知道是否有一些日志记录功能导致PowerShell挂起到字符串形式的管道绑定对象?
BTW在这种特定情况下,分配给$ null忽略输出的内存效率要高得多:
$null = GetDummyData
Run Code Online (Sandbox Code Playgroud)
此外,如果您只需编辑文件,请查看PowerShell Community Extensions 3.2.0中的Edit-File命令.只要不使用SingleString开关参数,它应该是内存有效的.
| 归档时间: |
|
| 查看次数: |
6126 次 |
| 最近记录: |