Skip to content
This repository has been archived by the owner on Sep 14, 2018. It is now read-only.

PythonContext leak #188

Open
deneuxj opened this issue Apr 11, 2014 · 3 comments
Open

PythonContext leak #188

deneuxj opened this issue Apr 11, 2014 · 3 comments
Assignees
Labels

Comments

@deneuxj
Copy link

deneuxj commented Apr 11, 2014

It seems that PythonContext objects created under the hood in hosted scripting can leak in some circumstances. From my observations, it seems normal and acceptable that the first instance of PythonContext remains live, and the same applies to the latest one.

Other instances, however, should be collected. This is important because PythonContext holds references to AST data that can get pretty large (I have observed 70 MB leaks at work).

The example below shows how to create leaks. Importing some modules triggers these leaks, but not all. For instance, sys is OK, but os leaks.

using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Scripting.Runtime;
using IronPython.Compiler;
using IronPython.Runtime;
using Microsoft.Scripting.Hosting.Providers;
using Microsoft.Scripting.Hosting;

namespace IronPythonLeak
{
    class Program
    {
        static readonly string code = @"
import os
";
        static WeakReference wr = null;

        static void AddSearchPath(ScriptEngine engine) {
            var sp = engine.GetSearchPaths();
// Set to your liking
            sp.Add(@"....\main\External.LCA_RESTRICTED\Languages\IronPython\27\Lib");
            engine.SetSearchPaths(sp);
        }

        static void RunOnce(bool storeLanguageContext)
        {
            var options = new Dictionary<string, object>();
            options["Frames"] = ScriptingRuntimeHelpers.True;
            options["FullFrames"] = ScriptingRuntimeHelpers.True;
            options["LightweightScopes"] = ScriptingRuntimeHelpers.True;
            var setup = IronPython.Hosting.Python.CreateLanguageSetup(options);
            setup.ExceptionDetail = true;
            var runtime = IronPython.Hosting.Python.CreateRuntime();            
            var engine = runtime.GetEngineByFileExtension("py");
            if (storeLanguageContext)
                wr = new WeakReference(HostingHelpers.GetLanguageContext(engine));
            var compilerOptions = (PythonCompilerOptions)engine.GetCompilerOptions();
            compilerOptions.Module |= ModuleOptions.Interpret;
            compilerOptions.Module &= ~ModuleOptions.Optimized;
            AddSearchPath(engine); // Needed if using freshly compiled, non-installed IronPython DLLs.
            engine.Execute(code);
            runtime.Shutdown();
        }

        static void Main(string[] args)
        {
            Console.Write(code);
            RunOnce(false);
            RunOnce(true);
            RunOnce(false);
            System.GC.Collect();
            if (wr.IsAlive)
                Console.Write("Leaked");
            else
                Console.Write("Not leaked");
            Console.ReadKey(true);
        }
    }
}
@slide
Copy link
Contributor

slide commented Dec 11, 2015

@jdhardy Another leak issue that may be solved by your updates.

@slide
Copy link
Contributor

slide commented Jul 28, 2016

This still shows "leaked" on master

@slide
Copy link
Contributor

slide commented Nov 4, 2016

@simplicbe Can you profile this one too?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants