我正在使用C#中的游戏引擎+编辑器。这个想法是用户将所有游戏代码写入编辑器将加载的项目中,因此它可以列出用户定义的类,并在场景编辑器中实例化它们。
使用(重新)加载DLL的概念,我可以加载DLL,实例化和调用外部程序集中定义的类的方法,重建外部程序集,并在主机中再次加载它,而无需重新启动主人。这项工作(至少它看起来像它),但它不会释放以前加载的组件的内存。
Loader class:
public class Loader
{
// This DLL contains an implementation of ILoadable - ILoadable is declared in a shared project.
private const string AsmPath = @"D:\Dev\AsmLoading\AsmLoadingImpl\bin\Debug\AsmLoadingImpl.dll";
public ILoadable GetExternalLoadable()
{
var asmBytes = File.ReadAllBytes(AsmPath);
Assembly asm = Assembly.Load(asmBytes, null);
var loadableInterface = typeof(ILoadable);
var loadableImpl = asm.GetTypes().First(loadableInterface.IsAssignableFrom);
return (ILoadable)Activator.CreateInstance(loadableImpl);
}
}
运行GetExternalLoadable()
2或3次,任务管理器显示我的宿主程序中RAM使用量增加了约1mb,重复相同的操作会进一步增加它,而不会减少。
有什么方法可以解决这个问题吗?我知道Unity正在做类似的事情,除了它们实际上自己编译外部程序集,但是当我触发重新编译几次时,Unity编辑器不会消耗额外的内存。
所以,我想要完成的是“实时重新加载”的外部程序集。
答案 0 :(得分:1)
.NET 4增加了对collectible assemblies的支持,可以由GC卸载。
然而,这些受到严格限制:
如果您的.dll符合这些限制,您可以加载并重新发出IL代码,使其看起来像是动态生成的.NET程序集。
除了动态方法和可收集的程序集之外,如果不卸载整个AppDomain,就无法卸载代码。