0

我们的 Biztalk 2006 应用程序包含两个经常调用的编排(大约每秒 15 个请求)。我们通过在主机中进行某些限制阈值更改来识别我们的应用程序中可能存在的内存泄漏。当我们禁用基于内存的限制时,进程内存开始增加到 1400 MB,之后我们开始遇到内存不足的异常。
发生这种情况时,我们被迫重新启动主机实例。
我们想知道在这种情况下,从 Orchestration 显式调用 GC.Collect 是否有效。使用这种方法有什么缺点?

谢谢。

4

5 回答 5

3

仅当垃圾收集器无法释放足够的内存来执行请求的分配时,才会发生内存不足异常。如果您有内存泄漏,则可能会发生这种情况,在垃圾收集平台中,这意味着某些对象引用的保留时间超过了它们需要的时间。泄漏的常见原因是保存全局数据(静态变量)的对象,例如保持引用时间过长的单例、缓存或池。

如果显式调用 GC.Collect,它也将无法释放内存,原因与隐式收集失败的原因相同。所以 explit GC.Collect 调用只会导致编排速度变慢。

如果您从编排中调用 .Net 类,我建议尝试通过从纯 .Net 应用程序调用相同的类来隔离问题(不涉及 BizTalk)

也有可能没有泄漏,但是每个实例同时消耗了太多内存。BizTalk 通常会在它认为有必要时使编排脱水,但如果编排(或大型原子范围)中的某个步骤执行时间过长,则可能会阻止这样做。

1400 mb 对于只有 15 个并发实例来说看起来也很大。您是否正在对编排中的大型消息进行操作?在这种情况下,您可以通过避免强制将整个消息加载到内存中的操作来大大减少内存使用量,而是使用流式处理消息。

于 2009-03-03T15:37:17.060 回答
1

不知道 Biztalk 我的答案可能很遥远……</p>

我假设在一个进程中运行的更多编排实例会增加单个编排实例完成所需的时间。然后,随着您增加让同时运行的编排实例的数量,在某些时候,它们完成所需的时间将足够大,以至于正在运行的编排实例的大小对您的 RAM 来说非常有用。

我认为您需要根据正在运行的编排实例的数量进行节流。如果您将“完成率”与“正在运行的编排实例数”绘制成图表,您可能会在图表中间看到一个大的平坦区域,选择您的节流以使您保持在这个稳定区域的中间。

于 2009-03-03T12:55:59.960 回答
0

I agree with the poster above. Trying to clear the memory or resetting the host instance is not the solution but just a band aid. you need to find where you are leaking memory. I would look at the whole Application and not just the orchestration; it is possible that the ports could also be causing your memory leak. Do you use custom functoids in your maps? how about inline code? Custom xslt? I would also look at custom pipelines if you are using them. If its possible i would try isolating the different components and putting them under stress and volume tests individually; somehow i dont think your orchestration itself is the problem, but rather a map or a custom component.

于 2009-03-03T16:05:09.397 回答
0

我完全同意其他人所说的大部分内容——你应该看看你的漏洞在哪里并修复它;直接致电 GC 对您没有帮助,而且在任何情况下都不太可能是一种合理的前进方式。

不过,我要补充一点,如果您遇到资源消耗突然增加,节流的存在是为了保护您的环境不会陷入停顿;如果不进行限制,BizTalk(与任何其他服务器一样)可能会达到无法继续处理并有效“卡住”的程度;节流允许它放慢速度,以确保处理仍在进行,直到资源消耗水平(希望)恢复到正常水平;

出于这个原因,我还建议您考虑为您的环境配置一些限制,必须调整其值以适应您的情况

于 2009-03-10T06:51:24.973 回答
0

进行垃圾收集不会释放泄漏的内存,因为它仍然(错误地)被您的应用程序以某种方式引用。如果您做了很多生成短期对象并且知道您正处于释放它们的好时机,您只会调用 GC.Collect。

您必须识别并修复泄漏代码!

于 2009-03-06T16:29:44.117 回答