【发布时间】:2011-10-28 20:38:36
【问题描述】:
我创建了一个运行插件的小型 Windows 服务。
每个插件都是一个 dll,它使用 CreateInstanceAndUnwrap 方法加载到自己的单独 AppDomain 中,我保留了对 AppDomain 的引用。
插件完成后,我关闭了为该插件创建的AppDomain。我正在使用卷影副本来允许在框架中运行时更新插件。
它已经完美运行了 6 个月,直到上周我决定将框架的核心功能也放入一个单独的 dll 并在单独的AppDomain 中执行该 dll。
它现在的工作方式是:
- Windows 服务启动。
- 核心 dll 使用
CreateInstanceAndUnwrap加载和执行,而CreateInstanceAndUnwrap又负责在各自独立的AppDomain中运行插件
我有几个不同的装配位置:
- Bin 文件夹(windows 服务的Bin 只保存服务使用的dll)
- Core DLLs 文件夹(Core dlls 放在这里)
- 参考资料文件夹(任何参考资料都放在这里)
- 插件文件夹(插件放在这里)
我通过连接AppDomain 上的每个OnAssemblyResolve 事件来解决任何未找到的dll。这允许通过网络加载 dll。
现在问题是windows服务跑了一天,内存高达1.5G。我创建了一个内存转储,似乎加载的模块只有整个 1.5G 的 100MB,所以我不知道所有这些内存都去哪里了。
使用调试时,我看到了堆碎片的警报,但我不知道应该从哪里开始诊断问题。通常,当框架运行一天时,它会消耗大约 100M。
这也与插件无关;当我回滚对框架的更改时,内存使用变得像以前一样正常。当我为插件创建 AppDomain 时,我将 AppDomain 的 basePath 和 bin 路径切换到 CORE 和 References 文件夹,其中包含大部分 dll,希望减少调用程序集解析的频率。
我查看了融合日志,还阅读了更多关于加载上下文的信息,例如 default、from 和 none,但我不确定这是否是正确的路径。
有什么想法吗?
【问题讨论】:
-
注册到
AssemblyResolve属性是新的吗? -
是否可以发布一些代码以提供更多信息?
-
为什么不使用
System.AddInnamespace 中的类?绝对没有理由自己编写这种代码。 -
是的,解决装配零件是新的。
-
已经很晚了,该项目与appdomains而不是system.addins非常耦合......所以现在别无选择。