Dot-Net

嵌入式 IronPython 記憶體洩漏

  • August 11, 2021

我需要一些幫助來解決我遇到的記憶體洩漏問題。我有一個 C# 應用程序 (.NET v3.5),它允許使用者執行 IronPython 腳本以進行測試。這些腳本可能會從 Python 標準庫(包含在 IronPython 二進製文件中)載入不同的模組。但是,當腳本完成時,分配給導入模組的記憶體不會被垃圾回收。循環執行一個腳本(用於壓力測試)會導致系統在長期使用期間記憶體不足。

這是我正在做的事情的簡化版本。

腳本類主要功能:

public void Run()
{
   // set up iron python runtime engine
   this.engine = Python.CreateEngine(pyOpts);
   this.runtime = this.engine.Runtime;
   this.scope = this.engine.CreateScope();

   // compile from file
   PythonCompilerOptions pco = (PythonCompilerOptions)this.engine.GetCompilerOptions();
   pco.Module &= ~ModuleOptions.Optimized;
   this.script = this.engine.CreateScriptSourceFromFile(this.path).Compile(pco);

   // run script
   this.script.Execute(this.scope);

   // shutdown runtime (run atexit functions that exist)
   this.runtime.Shutdown();
}

載入隨機模組的範例“test.py”腳本(增加約 1500 KB 記憶體):

import random
print "Random number: %i" % random.randint(1,10)

一種會導致系統記憶體不足的循環機制:

while(1)
{
   Script s = new Script("test.py");
   s.Run();
   s.Dispose();
}

我添加了該部分以不根據我在執行緒中找到的內容優化編譯,但是記憶體洩漏無論如何都會發生。添加對 s.Dispose() 的顯式呼叫也沒有任何區別(如預期的那樣)。我目前正在使用 IronPython 2.0,但我也嘗試升級到 IronPython 2.6 RC2,但沒有成功。

當腳本引擎/執行時超出範圍時,如何讓嵌入式 IronPython 腳本中的導入模組像普通 .NET 對像一樣被垃圾收集?

使用 Iron Python 2.6 RC 2 和 C# 3.5

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;

namespace IPmemTest {
   class IPy {
       private string script = "import random; random.randint(1,10)";

       public IPy() {
       }

       public void run() {
           //set up script environment
           Dictionary<String, Object> options = new Dictionary<string, object>();
           options["LightweightScopes"] = true;
           ScriptEngine engine = Python.CreateEngine(options);
           ScriptRuntime runtime = engine.Runtime;
           ScriptScope scope = runtime.CreateScope();
           var source = engine.CreateScriptSourceFromString(this.script);
           var comped = source.Compile();
           comped.Execute(scope);
           runtime.Shutdown();
           }
   }
}

我的循環是

class Program {
       static void Main(string[] args) {
           while (true) {
               var ipy = new IPy();
               ipy.run();
           }
       }
   }

記憶體使用量增加到大約 70,000K,但隨後趨於平穩。

引用自:https://stackoverflow.com/questions/1664567