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: [email protected] | 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
[email protected]
http://mail.python.org/mailman/listinfo/ironpython-users