Hi, Von: Markus Schaber >[Memory Leaks]
I now created a smaller stand-alone testcase simulating our environment, and isolated the following cases: - using Python.SetTrace(engine, delegate) leaks about 165k per script invocation. - importing the warning module from the hosting environment leaks about 1.4 M per script run. - importing the os module from the script also leaks about 1.4M per script. - Doing both imorts also leaks about 1.4M per script(!). - Combining all three of the above leads to an OutOfMemory Exception after about 331 cycles, boiling down to a leak of ~5MB per script run! - Doing none of the above (only print) apparently creates a leak-free program. I attached the test program. For the test runs above, I compiled it for .NET 4.0 and target "x86", as our production app also runs in that environment (.NET 4.0 and 32-bit only). I'll do further investigations (like memory dumping) tomorrow. Best regards Markus Schaber -- ___________________________ We software Automation. 3S-Smart Software Solutions GmbH Markus Schaber | Developer Memminger Str. 151 | 87439 Kempten | Germany | Tel. +49-831-54031-0 | Fax +49-831-54031-50 Email: m.scha...@3s-software.com | Web: http://www.3s-software.com CoDeSys internet forum: http://forum.3s-software.com Download CoDeSys sample projects: http://www.3s-software.com/index.shtml?sample_projects Managing Directors: Dipl.Inf. Dieter Hess, Dipl.Inf. Manfred Werner | Trade register: Kempten HRB 6186 | Tax ID No.: DE 167014915
 using System.Threading; namespace IronPythonLeakTest { using System; using System.Collections.Generic; using System.Runtime.InteropServices; using IronPython.Hosting; using IronPython.Runtime; using IronPython.Runtime.Exceptions; using IronPython.Runtime.Types; using Microsoft.Scripting; using Microsoft.Scripting.Hosting; using System.Windows.Forms; public static class ScriptExecutor { public static bool import_os = true; public static bool import_warnings = true; public static bool set_trace = true; private const string LIB_PATH = @"C:\Program Files (x86)\IronPython 2.7.1\Lib"; private static readonly Dictionary<string, object> DEFAULT_EXECUTION_OPTIONS = new Dictionary<string, object> { { "LightweightScopes", true } }; private static int TraceCount; private static void Main() { long afterFirst = 0; long beforeStart = 0; try { beforeStart = GC.GetTotalMemory(true); Execute(0); afterFirst = GC.GetTotalMemory(true); for (int i = 1; i < 1000; i += 1) { Execute(i); } } finally { for (int i = 0; i < 5; i += 1) { Application.DoEvents(); GC.Collect(); Thread.Sleep(1000); GC.WaitForPendingFinalizers(); } long afterLast = GC.GetTotalMemory(true); Console.WriteLine("Script Finished"); Console.WriteLine("First run: {0}Mb, 1000 runs: {1}Mb", (afterFirst - beforeStart) / (1024 * 1024), (afterLast - beforeStart) / (1024 * 1024)); Console.ReadLine(); } } private static void Execute(int i) { DateTime start = DateTime.Now; string src = "from __future__ import print_function \n"; if (import_os) src += "import os \n"; src += string.Format("print('hallo: ', {0}) \n", i); ScriptEngine engine = Python.CreateEngine(DEFAULT_EXECUTION_OPTIONS); ScriptRuntime runtime = engine.Runtime; ScriptScope mainScope = engine.CreateScope(); runtime.LoadAssembly(typeof(IronPython.Modules.PythonNT).Assembly); ScriptSource scriptSource = engine.CreateScriptSourceFromString(src, "TestScript", SourceCodeKind.AutoDetect); scriptSource.Compile(new global::IronPythonLeakTest.ErrorListenerImpl()); ScriptSource source = scriptSource; // Set the search pathes. engine.SetSearchPaths(new[] { LIB_PATH }); if (set_trace) { engine.SetTrace(TraceBackHandler); } if (import_warnings) { var warningModule = engine.ImportModule("warnings"); warningModule.SetVariable("showwarning", new ShowWarning(ShowWarning)); } source.Execute(mainScope); Console.WriteLine("{0}: {1} - {2}", i, ScriptExecutor.TraceCount, (DateTime.Now - start).Milliseconds); } private static void ShowWarning(CodeContext context, object message, PythonType category, string filename, int lineno, object file, string line) { Console.WriteLine(message ?? ""); } private static TracebackDelegate TraceBackHandler(TraceBackFrame stackFrame, string stEvent, object payload) { TraceCount += 1; return TraceBackHandler; } } public delegate void ShowWarning( CodeContext context, object message, PythonType category, string filename, int lineno, [DefaultParameterValue(null)] object file, [DefaultParameterValue(null)] string line); class ErrorListenerImpl : ErrorListener { public override void ErrorReported(ScriptSource source, string stMessage, Microsoft.Scripting.SourceSpan span, int errorCode, Microsoft.Scripting.Severity severity) { Console.WriteLine(stMessage); } } }
_______________________________________________ Ironpython-users mailing list Ironpython-users@python.org http://mail.python.org/mailman/listinfo/ironpython-users