2011-03-28 27 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