在过去的几天里,我一直试着找出appdomain问题。 我创建了一个运行插件的小型Windows服务。它的工作方式是,每个插件都是一个dll,使用“CreateInstanceAndUnwrap”加载到它自己的单独appdomain中,我保持对appdomain的引用,一旦插件完成,我关闭为该plugin.i创建的appdomain我们使用卷影副本来允许在框架中运行时更新插件。好到现在为止。它已经运行了6个月,直到上周我决定将框架的核心功能放入一个单独的DLL中并在一个单独的appdomain中执行该dll。所以它现在的工作方式是:
Windows服务出现。核心dll使用CreateInstanceAndUnwrap加载和执行,而CreateInstanceAndUnwrap又负责在他们自己的单独appdomains中运行插件 (使用CreateInstance和..)
我有几个不同的装配位置: Bin文件夹(Windows服务的bin仅包含服务使用的dll) 核心DLL文件夹(核心dll在这里被删除) 引用文件夹(此处删除任何引用) 插件文件夹(插件放在这里)
我通过连接每个 appdomain的onassemblyresolve处理程序来解决任何不合理的dll。 所以这意味着dll可以通过网络加载。
现在问题是Windows服务运行了一天,内存高达1.5G。 我创建了一个内存转储,似乎加载的模块只有整个1.5G的100MB,所以我不知道所有这些内存将去哪里。使用debugdiag我看到了堆碎片的警报,但我不知道我应该从哪里开始诊断问题。 通常当框架运行一天时,它消耗的东西就像100M。这也与插件无关,因为当我将我的更改回滚到框架时,memroy的使用变得像以前一样。 当我为插件创建appdomains时,我将appdomain的basePath和bin路径切换到其中包含大部分dll的CORE和References文件夹,希望不经常调用程序集解析。
我查看了聚合日志,并且还阅读了一些关于加载上下文的信息,例如default,from和none,但我不确定这是否是正确的路径。
有什么想法吗?
答案 0 :(得分:1)
我想这个:
当我决定将框架的核心功能放入一个 单独的DLL也在单独的appdomain中执行该DLL。所以 它现在的工作方式是:
Windows服务出现。核心dll被加载并执行使用 CreateInstanceAndUnwrap反过来负责运行 插件在他们自己的单独appdomains中(使用CreateInstanceand ..)
可能与此相冲突:
来自http://msdn.microsoft.com/en-us/library/3c4f1xde.aspx
如果对类型为T1的对象的方法M进行早期绑定调用 由CreateInstanceAndUnwrap返回,并且该方法生成一个 早期绑定调用程序集C中类型为T2的对象的方法 除当前组件或包含T1的组件外, 程序集C加载到当前应用程序域中。这个装载 即使早期对T1.M()的调用是在体内发生的,也会发生 DynamicMethod,或其他动态生成的代码。如果 当前域是默认域,无法卸载程序集C. 直到过程结束。
在这种情况下,您可以使用Reflection执行“适当”调用以消除早期绑定。