I believe I've discovered a memory leak in the parsing of literal values (numerics at least) in expressions. I have a server that runs 24/7 and receives workunits. The workunits contain expressions that are compiled when received. I noticed a memory leak and used JetBrains dotMemory to investigate. It indicated that there was a ConcurrentDictionary that was slowly accumulating objects. My app does not use ConcurrentDictionary. I subsequently narrowed this down to ConstantExpressionHelper. After 30 minutes of execution the ConcurrentDictionary contained 89K nodes.
Below is an app that will reproduce this problem. Because it is stripped down to the bare minimum required to reproduce the problem and is multithreaded you can watch the Visual Studio memory monitor for 30 seconds and you will see it slowly creeping up. This app starts out for me at about 32MB of memory and after 2 minutes it is at 84MB.
This app is currently using an expression consisting of a single number (simplest possible repro), but I found this with a much more complex numeric expression involving about 6 calls to Math.X operations and some floating point literals.
using System;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading;
namespace Utility.SoakTest
{
class Program
{
static void Main(string[] asArgs)
{
RunThreads(8, RawMemoryLeak);
}
private static void RunThreads(int nThreads, Action actThreadStart)
{
for (int i = 0; i < nThreads; i++)
{
Thread thread = new Thread(new ThreadStart(actThreadStart));
thread.Start();
}
while (true)
{
Thread.Sleep(5000);
}
}
private static void RawMemoryLeak()
{
while (true)
{
string sExpr = "1234567890";
LambdaExpression expr = DynamicExpressionParser.ParseLambda(new ParameterExpression[0], typeof(double), sExpr);
}
}
}
}
I believe I've discovered a memory leak in the parsing of literal values (numerics at least) in expressions. I have a server that runs 24/7 and receives workunits. The workunits contain expressions that are compiled when received. I noticed a memory leak and used JetBrains dotMemory to investigate. It indicated that there was a ConcurrentDictionary that was slowly accumulating objects. My app does not use ConcurrentDictionary. I subsequently narrowed this down to ConstantExpressionHelper. After 30 minutes of execution the ConcurrentDictionary contained 89K nodes.
Below is an app that will reproduce this problem. Because it is stripped down to the bare minimum required to reproduce the problem and is multithreaded you can watch the Visual Studio memory monitor for 30 seconds and you will see it slowly creeping up. This app starts out for me at about 32MB of memory and after 2 minutes it is at 84MB.
This app is currently using an expression consisting of a single number (simplest possible repro), but I found this with a much more complex numeric expression involving about 6 calls to Math.X operations and some floating point literals.