Tôi đã tạo tập lệnh PowerShell lặp lại trên một số lượng lớn tệp XML Schema (.xsd) và mỗi đối tượng tạo một đối tượng .NET XmlSchemaSet
, gọi Add()
và Compile()
để thêm lược đồ vào đó và in ra tất cả các lỗi xác thực.Làm thế nào để hướng dẫn PowerShell thu thập rác các đối tượng .NET như XmlSchemaSet?
Tập lệnh này hoạt động chính xác, nhưng có rò rỉ bộ nhớ ở đâu đó, khiến cho nó tiêu tốn gigabyte bộ nhớ nếu chạy trên 100 tệp.
Những gì tôi chủ yếu làm trong một vòng lặp như sau:
$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()
(Một kịch bản đầy đủ để tái tạo vấn đề này có thể được tìm thấy trong ý chính sau:. https://gist.github.com/3002649 Chỉ cần chạy nó, và xem sự gia tăng sử dụng bộ nhớ trong Task Manager hoặc Process Explorer.)
Lấy cảm hứng từ một số bài đăng trên blog, tôi đã cố gắng thêm
remove-variable reader, schemaSet
tôi cũng đã cố gắng chọn lên các $schema
fro m Add()
và đang thực hiện
[void] $schemaSet.RemoveRecursive($schema)
Điều này dường như có tác dụng nhưng vẫn bị rò rỉ. Tôi cho rằng các phiên bản cũ hơn của XmlSchemaSet
vẫn đang sử dụng bộ nhớ mà không bị thu gom rác.
Câu hỏi: Làm cách nào để dạy cho người thu gom rác đúng cách mà nó có thể đòi lại tất cả bộ nhớ được sử dụng trong mã ở trên? Hay nói chung hơn: làm thế nào tôi có thể đạt được mục tiêu của mình với một lượng bộ nhớ giới hạn?
Điều đó làm cho mức tăng ít hơn, vì vậy điều này có thể hữu ích trong thực tế; nhưng lượng bộ nhớ được sử dụng vẫn tăng dần. –
thêm '$ reader.Dispose()' sau khi đóng nó giúp ích nhiều hơn? –
Như được mô tả trong [một câu trả lời StackOverflow] (http://stackoverflow.com/a/745965/223837) điều này là không thể trực tiếp trong PowerShell, và nó không cần thiết vì 'Close()' ngụ ý một 'Dispose()' theo quy ước Microsoft được đề xuất. –