Web应用程序中IronPython内存泄漏的问题

时间:2011-03-28 14:49:49

标签: c# ironpython pygments

有没有人成功让IronPython在网络环境中毫无问题地运行?我遇到了一些问题。

第一个问题,我实际上并没有运行任何特定于IronPython的脚本,我正在实现Pygments库,因此我可以获得服务器端语法突出显示。该库大约有20多个文件。

除了最新的IronPython版本无法将脚本编译成DLL(由于this issue)之外,我确实通过将所有文件和依赖项复制到我的bin文件夹来成功运行。

问题是,我去看看我的w3wp.exe进程在进行突出显示时是如何做的,并注意到一些showstopper问题:

  • 即使在Cassini下的一个完全基本的空网站中,使用SQL词法分析器突出显示代码select * from table每次执行时都会导致10MB跳转(页面刷新)...我明确关闭关闭引擎并在单个函数调用中使用LightweightScopes。它从大约30MB开始,大约20次刷新,大约150MB左右。

  • 在我的实际Web应用程序中,使用SQL词法分析器(相同的代码)会导致我的应用程序池增加大约200MB /秒(字面意思是,当它达到大约1GB时我将其杀死),直到它崩溃w3wp或减慢我的速度PC爬行。这在空的测试站点中不会发生,并且在具有相同确切代码的控制台应用程序中完全没有问题。像C#这样的其他词法分析器不会导致巨大的内存泄漏,但每次调用函数时都会产生相同的增加内存的效果。

这使我相信这是一个特定于Web的问题,考虑到控制台应用程序没有任何问题(实例化运行时确实会导致内存增加20MB)。

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

我目前没有确切的代码,但它看起来像是:

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;

就像我说的,我将相同的代码复制到:a)控制台应用程序,b)全新的空网络应用程序,c)我的原始网络应用程序。控制台应用程序没有泄漏内存,但是网络应用程序没有。

我还使用本机Python(python myscript.py)和IPY(ipy myscript.py)执行了该函数,并且没有任何内存泄漏。

我是否缺少处理运行时的最佳实践?我计划在共享环境中运行它,因此在不同的应用程序池中实例化引擎的可能解决方法可能对我不起作用(同样,200MB / s的巨大泄漏也是一种显示)。

目前,除非某人有奇迹治愈,否则我打算废弃我的代码并使用Javascript语法荧光笔。这真是不幸,因为Pygments很棒......

1 个答案:

答案 0 :(得分:1)

这是一个很长的故事。 (TLDR,对不起)。这是.NET,你最有可能看到堆碎片而不是内存耗尽。

如果你真的泄漏了内存,那么你就会持续太长时间。回顾一下IDisposables(尤其是列表理解可能会受到影响,特别是对于Linqy这样的命令和明确的修改)。

我曾经使应用程序以2倍的速度运行,当它通过在最大的枚举上添加一个简单的.ToList()来驱逐一个大进程时,通过耗尽/分段堆而可靠地失败。

.NET有很好的内存分析器,但我目前知道如何只运行mono -profiler(坏内存)。一个简单的谷歌将帮助您找到可以在您的环境中使用的分析器:让它准确地告诉您分配哪些对象在哪里分割堆


PS。因为我看到你在第二次扫描你的问题时指着Web应用程序,我会补充:检查从会话状态(应用程序,会话)保持什么引用(间接)。