4

Web 環境で IronPython を問題なく実行できた人はいますか? いくつかの問題が発生しています。

最初の問題は、IronPython 固有のスクリプトを実際に実行していないことです。サーバー側の構文の強調表示を取得できるように、 Pygmentsライブラリを実装しています。ライブラリは約 20 個以上のファイルです。

最新の IronPython リリースでは (この問題により)スクリプトを DLL にコンパイルできないという事実に加えて、すべてのファイルと依存関係を bin フォルダーにコピーするだけで正常に実行できます。

問題は、強調表示を行っているときに w3wp.exe プロセスがどのように実行されているかを調べたところ、いくつかのショーストッパーの問題に気付いたことです。

  • Cassini の下の完全に基本的な空の Web サイトでもselect * from table、SQL lexer を使用してコードを強調表示すると、実行するたびに 10MB のジャンプが発生します (ページの更新)... エンジンを明示的にシャットダウンしLightweightScopes、単一の関数呼び出しで使用しています。約 30MB から開始し、約 20 回の更新で 150MB 程度になります。

  • 私の実際の Web アプリケーションでは、SQL lexer (同じコード) を使用すると、w3wp がクラッシュするか、PC の速度が遅くなるまで、アプリケーション プールが約 200MB/秒増加します (文字通り、約 1GB に達すると終了します)。これは空のテスト サイトでは発生せず、まったく同じコードのコンソール アプリではまったく問題はありません。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 ( python myscript.py) と IPY ( ipy myscript.py) の両方で関数を実行しましたが、どちらもメモリ リークはありませんでした。

ランタイムを破棄するために欠けているベストプラクティスはありますか? これを共有環境で実行する予定なので、別のアプリケーション プールでエンジンをインスタンス化するという可能な回避策は、おそらくうまくいかないでしょう (また、200MB/s でのその巨大なリークは一種のショーストッパーです)。

現在、誰かが奇跡的な治療法を持っていない限り、私は自分のコードを廃棄し、Javascript シンタックス ハイライターを使用する予定です。Pygmentsは素晴らしいので、本当に残念です...

4

1 に答える 1

1

それはかなり長い話です。(TLDR、申し訳ありません)。これは.NETであるため、メモリの枯渇ではなく、ヒープの断片化を確認している可能性があります。

あなたが本当にメモリリークをしているのなら、あなたは参照を長く保持しすぎています。IDisposablesを確認します(特に、リストの理解が損なわれる可能性があります。特に、orderbyやdistinctが付けられたLinqyの場合はそうです)。

私はかつて、アプリケーションを2倍の速度で実行しましたが、大きなプロセスを実行する必要があった最大の列挙に単純な.ToList()を追加することでヒープを使い果たしたり断片化したりして、確実に失敗していました。

.NETには優れたメモリプロファイラーがありますが、私は現在、mono --profiler(不良メモリ)のみを操作する方法を知っています。単純なグーグルは、環境で使用できるプロファイラーを見つけるのに役立ちます。ヒープを断片化している場所に割り当てられたオブジェクトを正確に教えてください。


PS。質問の2回目のスキャンでWebアプリケーションに指を向けているのを見たので、次のように追加します。セッション状態(アプリケーション、セッション)から(間接的に)保持されている参照を確認します。

于 2011-03-28T19:58:12.787 に答える