2016-01-23 158 views
0

使用Powershell v3,我使用.net庫類System.DirectoryServices.DirectoryEntrySystem.DirectoryServices.DirectorySearcher來查詢域中用戶的屬性列表。這個代碼基本上是found here新對象是否有內存泄漏?

您需要添加的唯一東西是行和$ds.PropertiesToLoad.AddRange($properties)之間的行$ds.PageSize=1000。這將消除只抓取1000個用戶的限制。

來自一個域的用戶數(我們稱之爲domain1)我已經有超過80,000個用戶。另一個域名(我們稱之爲domain2)擁有超過20萬用戶。

如果我在domain1上運行代碼,大約需要12分鐘(與使用的24小時Get-QADUser相比,這太棒了)。但是,腳本在PowerShell窗口中完成後,我注意到內存豬剩下約500MB。 Domain2留下了大約1.5gb的記憶豬。

注:Get-QADUser內存泄漏是非常非常更糟糕Domain2留下了大約6GB的內存豬,大約需要72小時才能完成(而.NET類不到一個小時)。

釋放內存的唯一方法是關閉PowerShell窗口。但是如果我想寫一個腳本來調用所有這些域腳本來一個接一個地運行它們呢?到達第六個腳本後,我會耗盡內存。

我能想到的唯一的事情是New-Object正在創建構造函數並且沒有析構函數(與java不同)。我在循環迭代期間嘗試使用[System.GC]::Collect(),但這沒有任何影響。

是否有原因?它是可解決的還是我堅持這個?

+0

我手邊沒有答案,但我可以告訴你你看到的不是特定於「新對象」的。即使使用'Get-Content'在一個.ps1文件運行時將大量數據存儲在一個變量中,似乎將數據緩存在內存中,即使該變量不直接可用(除非聲明範圍或點源)完成運行。我不認爲你所看到的是真正的內存泄漏。這是正常的。」 –

回答

1

有一點需要注意:如果實際上是內存泄漏,你可以運行該腳本在新shell:

powershell { <# your code here #> } 

至於泄漏,只要你有一個引用的變量持有大數據的對象無法收集。通過使用內存分析器查看內存中的內容和原因,您可能會有好運。據我所見,如果您在腳本文件中使用該代碼並執行腳本(&,而不是.!),那麼這應該不會發生。

+0

不幸的是,由於公司限制我們不使用任何工具,程序,編譯器或其他任何東西(包括來自Microsoft的rsat工具),因此我無法使用內存分析器。幸運的是,IT安裝了.net,因此我可以使用這些庫。我唯一允許使用的是Power GUI和Powershell v3(我甚至無法升級到v5)。我會嘗試在新的powershell過程中執行代碼的建議,並看看如何。謝謝。 –

+0

這一定會正常工作,內存被清除。我只需要弄清楚如何通過參數傳遞給它。 –

+0

@FiddleFreak:只需通過他們。如果您正在調用腳本,則只需附加參數,例如'powershell -File foo.ps1 arg1 arg2 ...'。 – Joey

0

我想這是使用所有內存的$table。爲什麼不直接將收集的數據寫入文件,而是將其添加到數組中?