简体   繁体   中英

CSharpScript memory leaks in ASP.NET core APi

I have an asp core api. A route can execute several c# scripts from database to get some calcul results on the same context/globals.

So I have this code:

    public static async Task<FormulaEvalException> TryEvalAsync<T>(this T formulaContext) where T : FormulaContext
    {
        FormulaEvalException res = null;
        ScriptState state = null;
        var scriptOptions = ScriptOptions.Default.WithReferences("System", "System.Linq", "System.Globalization", "Microsoft.CSharp").WithImports(new[] { "System", "System.Linq", "System.Math", "System.Globalization", "System.Collections.Generic" });
        foreach (var formulaList in formulaContext.AllFormulas.Values)
        {
            foreach (var formula in formulaList)
            {
                formulaContext.CurrentFormula = formula;
                try
                {
                    if (state == null)
                    {
                        state = await CSharpScript.RunAsync(formula.Script, scriptOptions, formulaContext);
                    }
                    else
                    {
                        state = await state.ContinueWithAsync(formula.Script);
                    }
                    var result = state.ReturnValue;
                    if (result == null)
                    {
                        if (res == null)
                        {
                            res = new FormulaEvalException(formula.Title + " : No result");
                        }
                        continue;
                    }

                    formula.Result = result;
                }
                catch (CompilationErrorException ex)
                {
                    if (res == null)
                    {
                        res = new FormulaEvalException(formula.Title + ex.Message);
                    }
                    continue;
                }
                catch
                {
                    continue;
                }
            }
        }

        return res;
    }

This code leads me to memory leaks and the user cannot repeat these requests.

From my previous searches, I got some informations as my formulaContext class as to located in another project. So I put it in a model project outside my API project. But I still have this issue.

I tried several way to execute my script (with CSharpScript.Create or CSharpScript.EvaluateAsync for example) but the memory is still not released.

I also heard about AppDomain class to execute my script in sandbox and release memory after using but AppDomain is not used anymore in ASP.NET Core.

Thank you for help ;)

Ok I found a fix :

                finally
                {
                    GC.Collect();
                }

The memory fall from more than 1 GB to 250 MG. I know, once an type or assembly is loaded, it can't be unloaded anymore but the formulas are very small so I suppose my memory was full because of the CSharpScript's compilation process.

I'm waiting now for the ability to unload assemblies to definitevely clean that. Apparently, it is planned : https://github.com/dotnet/coreclr/issues/552

Thank Tseng for your help.

Why are you guys tripping out so much. Unloading of Assemblies/Types is NOT supported in DotNet Core and is not going to be until 3.0.

I am working on a CMS/VFS for DotNet Core and this is the single biggest obstacle at the moment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM