4

有没有人成功让 IronPython 在 Web 环境中正常运行?我遇到了一些问题。

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

除了最新的 IronPython 版本无法将脚本编译成 DLL(由于这个问题)之外,我只需将所有文件和依赖项复制到我的 bin 文件夹即可成功运行它。

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

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

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

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

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

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

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) 一个全新的空 Web 应用程序,c) 我原来的 Web 应用程序。控制台应用程序不会泄漏内存,但 Web 应用程序会。

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

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

目前,除非有人有灵丹妙药,否则我打算废弃我的代码并使用 Javascript 语法荧光笔。这真的很不幸,因为 Pygments 很棒......

4

1 回答 1

1

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

如果您真的在泄漏内存,那么您对引用的持有时间太长了。回顾你的 IDisposables(尤其是列表理解可能会受到伤害,尤其是在 Linqy 的事情上,比如 orderby 和 distinct 附加)。

我曾经让一个应用程序的运行速度提高了 2 倍,当它通过在我必须驱动一个大进程的最大枚举上添加一个简单的 .ToList() 来耗尽/碎片化堆时可靠地失败了。

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


PS。因为我看到您在第二次扫描您的问题时将矛头指向 Web 应用程序,所以我要补充一点:检查会话状态(应用程序、会话)中持有哪些引用(间接)。

于 2011-03-28T19:58:12.787 回答