dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.08k stars 4.04k forks source link

Extremely high memory usage #33304

Open ashleyww93 opened 5 years ago

ashleyww93 commented 5 years ago

Version Used: 2.10.0

Steps to Reproduce: Code and paste the following code into a .net core 2.2 console app and run it.

using System;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;

namespace MyCode
{
    public static class MyClass
    {
        public static int MyFunc(int i)
        {
            return i;
        }
    }
}
namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {

            for (int i = 0; i < 2000; i++)
            {
                object a = CSharpScriptEngine.Execute("MyCode.MyClass.MyFunc(1)");//simple code
            }

            Console.ReadKey();
        }

        public class CSharpScriptEngine
        {
            private static ScriptState<object> scriptState = null;
            private static ScriptOptions ScriptOptions = ScriptOptions.Default.AddReferences(typeof(Program).Assembly);
            public static object Execute(string code)
            {
                   scriptState = scriptState == null ? CSharpScript.RunAsync(code, ScriptOptions).Result : scriptState.ContinueWithAsync(code).Result;

                if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
                    return scriptState.ReturnValue;
                return null;
            }
        }
    }
}

Expected Behavior: Low memory usage, being able to use complex formulas (not simple ones like above) in a release environment.

Actual Behavior: The applications memory usage is crazy high, you will easily hit 1gb of ram used in a few seconds, and it is never freed

0xd4d commented 5 years ago

Roslyn doesn't seem to cache the metadata by default, so it allocates more and more memory. You can create your own metadata resolver (that calls the original md resolver) and cache the result.