ironpython2 icon indicating copy to clipboard operation
ironpython2 copied to clipboard

Memory leak when importing ctypes

Open SteveUM opened this issue 7 years ago • 3 comments

Version 2.7.7 When executing a script from C#, if we create the ScriptEngine object each iteration, we see a large memory leak when importing the ctypes module. If we use the same script, but do not import ctypes, no memory leak. This may be related to issue #114

It appears that a work around to this is to create a single instance of the ScriptEngine and re-use it.

The following code shows the issue:

        static void Main(string[] args)
        {
            IDictionary<string, object> options = new Dictionary<string, object>();
            options["LightweightScopes"] = true;
            options["MTA"] = true;
            Run3(100, @"import sys; sys.path.append(r'W:\Program Files (x86)\IronPython 2.7\Lib'); import ctypes;  print 'ctypes loaded'", options);
            Console.ReadKey();
            Run3(100, @"import sys; sys.path.append(r'W:\Program Files (x86)\IronPython 2.7\Lib'); print 'ctypes not loaded'", options);
            Console.ReadKey();
        }
        public static void Run3(int iterations, string script, IDictionary<string, object> args)
        {
            //ScriptEngine engine = Python.CreateEngine(args); // creating only a single engine removes the leak
            Console.WriteLine($"---Start---");
            for (int i = 0; i < iterations; i++)
            {
                Thread t = new Thread(() =>
                {
                    ScriptEngine engine = Python.CreateEngine(args); // remove this if creating outside of loop
                    ScriptSource source = engine.CreateScriptSourceFromString(script, SourceCodeKind.File);
                    CompiledCode cc = source.Compile();
                    cc.Execute();
                    Process p = System.Diagnostics.Process.GetCurrentProcess();
                    Console.WriteLine($"memory: {(p.WorkingSet64 / 1024)}");
                    engine.Runtime.Shutdown();
                });
                t.Start();
                t.Join();
            }
            Console.WriteLine($"---end---");
        }

SteveUM avatar Sep 20 '17 14:09 SteveUM

The issue sounds familiar but I can't seem to find where I've seen it before. I don't think the issue is specific to ctypes but occurs with most module imports.

slozier avatar Sep 25 '17 16:09 slozier

Although we don't import many modules, we've only found the issue when using ctypes. I'm sure you're correct that it happens to more than just ctypes.

For the work around, does anyone know if "engine.Runtime.Shutdown()" sets the engine to its initial state? If we're going to reuse the engine between executions, we want to make sure all previous variables/objects are cleared out.

SteveUM avatar Sep 28 '17 12:09 SteveUM

No, as far as I can tell Shutdown does not set the engine to its initial state, it performs a shutdown. If you want your executions to be "independent" of each other you can try executing you code in different scopes:

var scope = engine.CreateScope();
cc.Execute(scope);

slozier avatar Sep 28 '17 14:09 slozier