使用CSharpScript接口限制内存使用

时间:2017-01-09 16:34:35

标签: c# roslyn

我有一个应用程序,我使用大量CSharpScript个实例来控制应用程序。我面临的问题是内存使用量在很大程度上取决于我使用的全局对象的类型。如果在我的应用程序集(大型程序集)中定义了全局类型,则每个编译脚本的内存使用量将增加约100MB。如果我将全局类型放在一个单独的程序集中,我会发现每个脚本的内存使用量增加了大约10MB,这对于我使用的脚本数量来说仍然很多。

使用CSharpScript API时有没有办法限制内存使用量?

2 个答案:

答案 0 :(得分:2)

我认为这里发生的是你的脚本直接引用主应用程序中定义的对象。由于脚本编译为单独的AppDomain,因此AppDomain会从主应用程序的AppDomain中提取自己的本地副本。由于你有100个脚本,每个脚本都在自己的AppDomain中,你的主程序集会被加载100次。

避免这种情况的一种方法是让脚本和应用程序之间的任何接口通过" shim"对象,它是一个小类,在它自己的程序集中定义,可以"序列化"跨越AppDomain边界的数据。 Shim类应该继承自MarshalByReferenceObject。这可能是棘手而复杂的,因为垫片不能通过应用程序中定义的任何类,或者它会吸入"吸入"主组件就像以前一样。一切都必须作为.NET中定义的类传递。

作为基类的MarshalByReferenceObject允许填充程序跨越域边界而不引入程序集的整个副本。更多信息可以在 https://msdn.microsoft.com/en-us/library/system.marshalbyrefobject(v=vs.110).aspx#Remarks

答案 1 :(得分:0)

我不知道您的具体实施是什么,但您可以这样做:

不是使用大量的全局对象将数据提供给脚本,而是让脚本只为应用程序提供逻辑:

代替此csx文件,将HeavyObject作为全局:

// script.csx:
HeavyObject.DoSomeWork();

你可以编写这个csx,不需要全局参数:

// betterscript.csx:
public class ScriptWork : IHaveWork
{
    Work(HeavyType obj)
    {
        obj.DoSomeWork();
    }
}
return new ScriptWork();

您的应用中需要此界面:

public interface IHaveWork
{
    void Work(HeavyType obj);
}

并且脚本应该与您的应用程序的引用一起运行。 您将从脚本中收到IHaveWork的实例,然后您应该在应用程序中调用Work。