Quantcast
Channel: ClearScript
Viewing all articles
Browse latest Browse all 2297

New Post: Does ClearScript have memory leak?

0
0
Hi ClearScript,

I would try to provide as more information as possible.

Users can execute some custom scripts targets to our system, in our server side, we plan to use ClearScript(V8ScriptEngine) to parse and execute the input scripts. All the scripts are independent, they can be run concurrently, so no reused data left over by others.

Speaking of memory leaks, we have some simple codes to demonstrate it.
public class TestData
{
    private readonly string _bigData;

    public TestData()
    {
        _bigData = new string('*', 1024 * 1024);
    }

    public Guid Id { get; set; }

    public DateTime Created { get; set; }
}

public class CloudService
{
    public double Calculate(double num1, double num2)
    {
        return num1 + num2;
    }

    public TestData CreateObj()
    {
        return new TestData
        {
            Created = DateTime.Now,
            Id = Guid.NewGuid()
        };
    }

    public void Output(object obj)
    {
        EngineContext.Output.WriteLine(obj);
    }
}
And we exposed CloudService like this:
ScriptEngine.AddHostObject("service", new CloudService());
Here is how we execute the scripts:
public void RunScript()
{
    const int loopNumber = 100;
    double totalTime = 0;
    var output = string.Empty;
    for (var i = 0; i < loopNumber; i++)
    {
        try
        {
            var stopwatch = Stopwatch.StartNew();
            ScriptEngine.Execute(Scripts);
            stopwatch.Stop();
            totalTime += stopwatch.Elapsed.TotalMilliseconds;
            output = EngineContext.Output.ToString();
        }
        catch (Exception ex)
        {
            output = ex.ToString();
        }

        EngineContext.Output.GetStringBuilder().Clear();
    }

    Output = string.Format("{0}{1}{4} {1}Execution Performance:{1}\rTotal: {2} ms{1}\rAverage: {3} ms.", output,
        Environment.NewLine, totalTime, totalTime / loopNumber,"=========================");
}
We executed the input scripts 100 times to evaluate the performance. The ScriptEngine is global instance, which means we reused it for every script execution.

And the test script:
var obj = service.CreateObj();
service.Output(obj.Id);
We found the memory increased 200MB after the execution, and mostly are HostItem instance(200+ count), all of them has TestData instance with 1MB big data field. Besides that, we fired a timer which call ScriptEngine.CollectGarbage(true) every 1 second, it doesn't help too much.

We use dotMemory to detect the memory issue, here are two screenshots:
Memory Clue
HostItem

Here is our question

  1. Did we use ClearScript in wrong way? You can check the full code here. Use global ScriptEngine instance or create one each time in our scenario?
  2. Can you introduce the cache mechanism succinctly? For example, if all the input scripts are same, ClearScript will cache the only one copy in memory to increase performance or cache every scripts? Do we need to cache it by ourselves?
  3. What's the next release plan, we don't want to compile source code by ourselves?

Viewing all articles
Browse latest Browse all 2297