应用程序域内存问题

发布于 2024-12-12 12:09:32 字数 1092 浏览 0 评论 0原文

我创建了一个运行插件的小型 Windows 服务。

每个插件都是一个 dll,使用 CreateInstanceAndUnwrap 方法加载到其自己单独的 AppDomain 中,并且我保留对 AppDomain 的引用。

插件完成后,我关闭为该插件创建的 AppDomain。我使用卷影复制来允许在框架中运行时更新插件。

它已经完美运行了 6 个月,直到上周我决定将框架的核心功能也放入一个单独的 dll 中,并在单独的 AppDomain 中执行该 dll。

现在的工作方式是:

  1. Windows 服务启动。
  2. 核心 dll 使用 CreateInstanceAndUnwrap 加载并执行,后者负责在自己单独的 AppDomain 中运行插件。

我有几个不同的程序集位置:

  • Bin 文件夹(Bin Windows 服务仅包含该服务使用的 dll)
  • 核心 DLL 文件夹(核心 dll 放入此处)
  • 引用文件夹(任何引用放入此处)
  • 插件文件夹(插件放入此处)

我解决了任何未找到的问题通过连接到 AppDomain 上的每个 OnAssemblyResolve 事件来加载 dll。这允许通过网络加载 dll。

现在问题是windows服务运行一天,内存高达1.5G。我创建了内存转储,看起来加载的模块只有整个 1.5G 中的 100MB,所以我不知道所有这些内存会去哪里。

使用调试时,我看到了堆碎片警报,但我不知道应该从哪里开始诊断问题。通常框架运行一天会消耗100M左右。

这也与插件无关;当我回滚对框架的更改时,内存使用变得像以前一样正常。当我为插件创建AppDomain时,我将AppDomain的basePath和bin路径切换到CORE和References文件夹,其中包含大多数dll,希望程序集解析被调用的频率较低。

我查看了融合日志,还阅读了更多有关加载上下文的信息,例如默认、来自和无,但我不确定这是否是正确的路径。

有什么想法吗?

I have created a small windows service that runs plugins.

Each plugin is a dll that gets loaded into its own seperate AppDomain using CreateInstanceAndUnwrap method and I keep a reference to the AppDomain.

Once the plugin completes, I shut down the AppDomain that is created for that plugin. I'm using shadow copy to allow updates to the plugins while they are running in the framework.

It has run for 6 months perfectly untill last week when I decided to put the core functionality of the framework into a seperate dll also and execute that dll in a seperate AppDomain.

The way it works right now is:

  1. Windows service comes up.
  2. The core dll is loaded and executed using CreateInstanceAndUnwrap which in turn is responsible for running the plugins in their own seperate AppDomain

I have couple of different locations for assemblies:

  • Bin Folder (Bin of the windows service holds only dlls used by the service)
  • Core DLLs Folder (Core dlls get dropped in here)
  • References Folder (any references get dropped in here)
  • Plugins Folder (plugins get dropped in here)

I resolve any unfound dlls by hooking up to each the OnAssemblyResolve event on the AppDomain. This allows dlls to be loaded from over the network.

Now the problem is the windows service ran for one day and the memory went as high as 1.5G. I created a dump of the memory and seems like loaded modules are only 100MB of the whole 1.5G so I dont know where all this memory is going to.

Using debugging I saw an alert for heap fragmentation but I have no idea where I should start to diagnose the issue. Usually when the framework runs for a day it consumed something like 100M.

Also this is not related to the plugins either; when I rolled back my changes to the framework the memroy usage became normal as before. When I create the AppDomain for plugins, I switch the basePath and the bin path of the AppDomain to CORE and References folders that have most of the dlls in there in hope that the assembly resolve gets called less often.

I looked at fusion logs and also read a little bit more about load contexts like default, from, and none but im not sure if thats the right path to take.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羞稚 2024-12-19 12:09:32

您应该尝试下载 SciNet 内存分析器。我确实使用该工具来诊断服务问题,它确实有助于找出问题所在。有一个免费的评估版本可用。

如果您不能或不想安装它,您可以尝试将插件分成两半,看看它们是否具有相同的内存行为。您也可以尝试完全不使用任何插件。

此外,跨应用程序域的垃圾收集对象似乎棘手。您可能想调查一下。

You should try downloading SciNet memory profiler. I did use that tool to diagnose problems with services and it really does help to figure out where the issue is. There is a free evaluation version available.

If you cannot or do not want to install it, you can try to split your plugins in 2 halfs and see if they have the same memory behavior. You can also try with no plugins at all.

Also, Garbage collecting object across App domains seems to be tricky. You might want to investigate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文