powershell - 如何指示 PowerShell 对 XmlSchemaSet 等 .NET 对象进行垃圾收集?

标签 powershell memory-leaks garbage-collection xsd xmlschemaset

我创建了一个循环大量 XML Schema (.xsd) 文件的 PowerShell 脚本,并为每个文件创建一个 .NET XmlSchemaSet 对象,调用 Add() Compile() 向其中添加模式,并打印出所有验证错误。

该脚本可以正常工作,但是某处存在内存泄漏,如果在 100 多个文件上运行,它会消耗千兆字节的内存。

我基本上在一个循环中做的是以下内容:

$schemaSet = new-object -typename System.Xml.Schema.XmlSchemaSet
register-objectevent $schemaSet ValidationEventHandler -Action {
    ...write-host the event details...
}
$reader = [System.Xml.XmlReader]::Create($schemaFileName)
[void] $schemaSet.Add($null_for_dotnet_string, $reader)
$reader.Close()
$schemaSet.Compile()

(可以在此要点中找到重现此问题的完整脚本:https://gist.github.com/3002649。只需运行它,然后在任务管理器或进程资源管理器中观察内存使用量的增加。)

受一些博客文章的启发,我尝试添加
remove-variable reader, schemaSet

我也试过拿起$schema来自 Add()和做
[void] $schemaSet.RemoveRecursive($schema)

这些似乎有一些效果,但仍然存在泄漏。我假设 XmlSchemaSet 的较旧实例仍在使用内存而没有被垃圾收集。

问题:我如何正确地教垃圾收集器它可以回收上面代码中使用的所有内存?或更笼统地说:我怎样才能用有限的内存来实现我的目标?

最佳答案

Microsoft 已确认这是 PowerShell 2.0 中的一个错误,并且他们声明这已在 PowerShell 3.0 中得到解决。

问题是使用 Register-ObjectEvent 注册的事件处理程序没有被垃圾收集。在回复支持电话时,微软表示

"we’re dealing with a bug in PowerShell v.2. The issue is caused actually by the fact that the .NET object instances are no longer released due to the event handlers not being released themselves. The issue is no longer reproducible with PowerShell v.3".



就我所见,最好的解决方案是在不同级别的 PowerShell 和 .NET 之间进行接口(interface):完全在 C# 代码中进行验证(嵌入在 PowerShell 脚本中),然后返回 ValidationEventArgs 的列表。对象。请参阅 https://gist.github.com/3697081 上的固定复制脚本:该脚本在功能上是正确的,并且不会泄漏任何内存。

(感谢 Microsoft 支持帮助我找到此解决方案。)

最初,Microsoft 提供了另一种解决方法,即使用 $xyzzy = Register-ObjectEvent -SourceIdentifier XYZZY ,然后在最后执行以下操作:
Unregister-Event XYZZY
Remove-Job $xyzzy -Force

然而 ,此解决方法在功能上不正确。在执行这两个附加语句时,任何仍在“进行中”的事件都会丢失。就我而言,这意味着我错过了验证错误,因此我的脚本输出不完整。

关于powershell - 如何指示 PowerShell 对 XmlSchemaSet 等 .NET 对象进行垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11222961/

相关文章:

javascript - 如何解释 chromium 的 "Record Heap Allocations"图?

c# - 即使在需要时也不会发生垃圾收集

powershell - 大文本文件的匹配操作速度问题

svn - 如何防止 "svn diff"在 Windows 上生成 Unicode 输出

powershell - 替换powershell中变量的一部分而不替换其余部分?

java GC周期性的进入几个full GC周期

objective-c - 无法访问的对象在变得无法访问后是否随时都可以安全地收集?

sql-server - Excel.Application 不能使用 SQL 作业在 PowerShell 中运行,但可以从命令行运行

c++ - 无法解决内存泄漏

c++ - 内存泄漏 - STL 集