TFS 自動建構期間消耗的記憶體過多
我們正在執行 TFS 2010 標準版,並且我們設置了一個自動建構,以便在有人簽入程式碼時執行。作為建構的一部分,我們執行了所有自動化測試(使用 MSTest 建構)。我們已將建構配置為將測試作為 64 位程序執行,但執行測試的 QTAgent.exe 在測試執行時會在記憶體中增長。對於我們進行的約 650 次測試,它目前達到 8GB,當我們從 450 次測試增加到 650 次測試時,這個過程顯著減慢。
當我們在本地開發環境中執行所有測試時,記憶體似乎至少隨著每個 TestClass 被釋放,並且從未超過某個級別。在本地開發環境中執行所有測試的過程並沒有顯著增加。
有沒有辦法配置建構服務以釋放每個測試或每個測試類的記憶體?按照目前的執行方式,當我們開始耗盡機器上的記憶體時,建構過程會變得非常緩慢。
編輯:我在建構日誌中找到了 MSTest 呼叫並手動執行它並看到失控記憶體的相同行為。我從 MSTest 的呼叫中刪除了 /publish、/publishbuild、/teamproject、/platform 和 /flavor 參數,以防測試執行程序一直保留結果直到最後,但行為沒有改變。我在開發盒上執行相同的命令行,與建構伺服器分開,並且經常釋放記憶體。似乎建構伺服器一定有什麼錯誤/不同導致它的行為不同,但我很難看哪裡。
我查看了兩個執行檔的 qtagent.exe.config、mstest.exe.config 版本。還有什麼可能影響這一點?
我最終找到了在自動建構期間記憶體消耗如此之快的原因。通過創建 QTAgent.exe 的轉儲,我們能夠檢查其內容以查找 .NET 堆上的內容。事實證明,我們將大量對象放入記憶體對像中,並且由於記憶體對象存在於整個程序中,因此所有這些對像都在垃圾收集中倖存下來。
我們測試中的程序邏輯會生成一些隨機數據,然後檢查該數據是否唯一。在大多數情況下,它應該是,但偶爾會發生碰撞。如果發生衝突,我們最終會記憶體以前的數據。這應該不是問題,因為我們的測試在完成後會清理他們的數據,因此碰撞的風險應該相對較低。
通過檢查記憶體中的內容,我們發現我們一定遇到了很多衝突,並且由於一些不正確的依賴項配置,我們的清理邏輯僅在自動建構/測試環境中失敗。這意味著每次我們執行測試時,我們都會生成更多沒有被清理的數據,隨後的執行將冒著在測試執行期間將該數據載入到記憶體中的風險。
我承認測試不是完全孤立是我們問題的一部分,但我想指出一些其他的經驗教訓:
- 當從 Visual Studio 呼叫 MSTest 時沒有發生同樣的事情時,測試代理會以一種會導致記憶體失控的方式保留測試結果,這是不正確的。
- 能夠使用 WinDbg 和轉儲分析等工具來查看程序中記憶體中的內容非常有用。