2011-03-28 52 views
4

有沒有人成功地在Web環境中運行IronPython而沒有問題?我遇到了一些問題。Web應用程序中的IronPython內存泄漏問題

第一個問題,我沒有真正運行任何IronPython特定的腳本,我正在實現Pygments庫,因此我可以獲得服務器端語法高亮顯示。該圖書館大約有20多個文件。

除了這個事實,最新發布的IronPython不能編譯腳本到一個DLL(由於this issue),我確實有它通過剛纔的所有文件和依賴複製到我的bin文件夾運行成功。

的問題是,我去看看我的W3wp.exe進程是如何做的突出做的時候,發現了一些問題攪局者:

  • 即使在卡西尼下完全基本的,空的網站,突出使用SQL詞法分析器的代碼select * from table每次執行時都會導致10MB的跳轉(頁面刷新)...我正在關閉引擎,並在單個函數調用中使用LightweightScopes。它從大約30MB開始,大約有20次刷新,大約在150MB左右。

  • 在我實際的Web應用程序,使用SQL詞法分析器(相同的代碼)會導致我的應用程序池增加約200MB /秒(從字面上看,我殺了它,當它達到約1GB),直到它崩潰W3WP或減慢我的電腦下到爬行。這不會發生在空的測試站點,並且在控制檯應用程序中使用相同的確切代碼完全沒有問題。像C#這樣的其他詞法分析器不會導致巨大的內存泄漏,但每次調用該函數時都具有增加內存的效果。

這使我相信這是一個特定的網絡問題,考慮到控制檯應用程序沒有任何問題(實例運行確實導致內存一個20MB的增加,雖然)。

我正在使用2.7 IPY版本和1.4版本的Pygments。

我沒有跟我此刻的確切的代碼,但它看起來是這樣的:一)一個控制檯應用程序,B)A:

var options = something; 
options["LightweightScopes"] = ScriptRuntimeHelpers.True; // from another SO post, 'true' didn't seem to work 
var engine = Python.CreateEngine(options); 
// 
// set up search paths here... 
// 
dynamic scope = whatever; 
ScriptSource source = engine.CreateScriptSourceFromFile("myscript.py"); 

// Execute? Compile? It populates the scope at this point... 
source.Compile(scope); 

// execute (code, lexer name, style) 
// this is a python function I have that calls the Pygments code 
var highlighted = scope.generate_html("select * from table", "sql", "monokai"); 

engine.Shutdown(); 
return highlighted; 

就像我說的,我在複製相同的代碼全新的空網站應用程序,c)我的原創網站應用程序。控制檯應用程序沒有泄漏內存,但Web應用程序可以。

我還用本機Python(python myscript.py)和IPY(ipy myscript.py)執行了這個函數,並且都沒有任何內存泄漏。

是否有一些最佳實踐我丟失處置運行時?我計劃在一個共享的環境中運行它,所以在不同的應用程序池中實例化引擎的可能解決方法可能對我不起作用(另外,200MB/s的巨大泄漏也是一種炫耀)。

目前,除非有人有奇蹟般的治療方法,否則我打算取消我的代碼,只是用Javascript語法高亮顯示。這真是不幸,因爲Pygments太棒了...

+0

你真的創建引擎和執行每個請求的代碼?如果是的話,你或許應該切換到節能從scriptSource.Compile()的結果,然後調用執行的編譯代碼重複。 – 2011-03-29 05:48:25

+0

迪諾說什麼。另外,你的控制檯應用程序格式多次,或只是一次,然後退出? – 2011-03-29 15:02:29

+0

@迪諾,是的,我一直在使用它作爲一個單引擎,將引擎和腳本源保存爲靜態變量,但我也會嘗試按照您的建議進行操作。 @Jeff,我*曾經運行過一次......我發現Web應用程序中的問題出現在第一個請求中,所以它應該在應用程序啓動時出現,我有一個'Console.ReadKey()'我等了,我沒有看到記憶力上升。 – kamranicus 2011-03-30 01:39:06

回答

1

這是一個相當長的故事。 (TLDR,抱歉)。這是.NET,你很可能看到堆碎片而不是內存耗盡。

如果你真的泄漏內存則太長,你持有到引用。檢查您IDisposables(尤其是列表解析可以傷害,尤其是Linqy之類的排序依據和獨特上漲了)。

我曾經做過一個應用程序,運行速度是2x的速度,當它通過在最大的枚舉上加上一個簡單的.ToList()來耗盡/碎片化堆時,我不得不驅動一個大進程,從而可靠地失敗。

有用於.NET美好的回憶剖析,但我現在知道如何操作只有單聲道--profiler(壞的內存)。一個簡單的谷歌將幫助您找到您可以在您的環境中使用分析器:讓它告訴你到底對象分配什麼樣的地方你的碎片化堆


PS。因爲我看見你指着你的問題的第二次掃描Web應用程序的手指,我想補充:檢查什麼引用(間接)正在從會話狀態(應用,會話)舉行。

+0

謝謝,我會研究一下內存分析器。 – kamranicus 2011-03-29 03:50:52