我有一个应用程序,其中我使用了大量的CSharpScript实例来控制应用程序。我面临的问题是,内存使用在很大程度上取决于我使用的全局对象的类型。如果在我的应用程序程序集中定义了全局类型(巨大的程序集),那么对于每个编译过的脚本,内存使用量会增加大约100MB。如果我把全局类型放在一个单独的程序集中,我发现每个脚本的内存使用量增加了大约10MB,这对于我正在使用的脚本数量来说仍然很多。
在使用CSharpScript应用编程接口时,有没有办法限制这种内存使用?
发布于 2017-01-10 01:27:29
我认为这里发生的情况是,您的脚本直接引用了主应用程序中定义的对象。由于脚本被编译到一个单独的AppDomain中,这会导致该AppDomain从主应用程序的AppDomain中拉入自己的本地副本。因为你有100个脚本,每个脚本都在它们自己的AppDomain中,你的主程序集被加载了100次。
避免这种情况的一种方法是让脚本和应用程序之间的任何接口通过“填充”对象传递,“填充”对象是在自己的程序集中定义的一个小类,可以跨AppDomain边界“序列化”数据。该填充类应该从MarshalByReferenceObject继承。这可能是棘手和复杂的,因为填充程序不能传递应用程序中定义的任何类,否则它将像以前一样“吸收”主程序集。所有内容都必须作为.NET中定义的类进行传递。
作为基类的MarshalByReferenceObject允许填充程序跨域边界,而无需引入程序集的整个副本。欲了解更多信息,请访问https://msdn.microsoft.com/en-us/library/system.marshalbyrefobject(v=vs.110).aspx#Remarks。
发布于 2017-01-10 03:30:34
我不知道您的具体实现是什么,但您可能会这样做:
你可以让脚本只给你的应用程序提供逻辑,而不是使用大型的全局对象将数据提供给你的脚本:
而不是这个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。
https://stackoverflow.com/questions/41552619
复制相似问题