我们的Biztalk 2006应用程序包含两个频繁调用的编排(每秒约15个请求)。我们通过在主机中执行某些限制阈值更改来确定应用程序中可能存在的内存泄漏。当我们禁用基于内存的限制时,进程内存开始增加到1400 MB,之后我们开始遇到内存不足异常。
发生这种情况时,我们被迫重启主机实例
我们想知道在这种情况下,从Orchestration显式调用GC.Collect是否富有成效。什么可能是使用这种方法的缺点?
感谢。
答案 0 :(得分:3)
只有当垃圾收集器无法释放足够的内存来执行请求的分配时,才会发生内存不足异常。如果您有内存泄漏,这可能会发生,在垃圾收集平台中,这意味着某些对象引用保留的时间比他们需要的长。泄漏的常见原因是保存全局数据(静态变量)的对象,例如单个参数,缓存或保持引用时间过长的池。
如果显式调用GC.Collect,它也将无法释放内存,原因与隐式收集失败的原因相同。因此,explit GC.Collect调用只会导致业务流程变慢。
如果您从业务流程中调用.Net类,我建议尝试通过从纯.Net应用程序调用相同的类来解决问题(不涉及BizTalk)
也可能没有泄漏,但每个实例同时消耗太多内存。 BizTalk通常可以在发现必要时对业务流程进行脱水,但如果业务流程(或大型原子范围)中的某个步骤执行时间过长,则可能会阻止这样做。
1400 mb对于仅15个并发实例看起来也很大。您是否正在对业务流程中的大型消息进行操作?在这种情况下,您可以通过避免强制整个消息加载到内存中的操作来大大减少内存使用量,而是使用流式处理消息。
答案 1 :(得分:1)
不知道Biztalk我的答案可能会有所改变......
我假设在一个进程中运行的更多业务流程实例会增加单个业务流程实例完成所需的时间。然后,当您增加同时运行的业务流程实例的数量时,在某些时候,它们完成所需的时间将足够大,以至于正在运行的业务流程实例的大小对于您的RAM而言非常好。
我认为您需要根据运行的业务流程实例的数量进行限制。如果您将“完成率”与“正在运行的业务流程实例的数量”进行对比,您可能会在图表中间看到一个大的平坦区域,选择您的限制以使您处于此稳定区域的中间位置。
答案 2 :(得分:0)
我同意上面的海报。试图清除内存或重置主机实例不是解决方案,而只是一个乐队援助。你需要找到泄漏记忆的地方。我会看整个应用程序而不仅仅是编排;端口可能也会导致内存泄漏。你在地图中使用自定义functoid吗?内联代码怎么样?自定义xslt? 如果您使用它们,我也会查看自定义管道。 如果可能的话,我会尝试隔离不同的组件并将它们分别置于压力和体积测试之下;不知怎的,我不认为你的编排本身就是问题,而是地图或自定义组件。
答案 3 :(得分:0)
执行垃圾收集不会释放泄漏的内存,因为它仍然(错误地)以某种方式引用您的应用程序。你只会调用GC.Collect,如果你做了很多生成短命的对象,并且知道你有一个很好的点来释放它们。
您必须识别并修复泄漏的代码!
答案 4 :(得分:0)
我完全同意对方说的大部分内容 - 你应该看看你的泄漏在哪里并修复它;直接调用GC对你没有帮助,在任何情况下都不太可能成为合理的前进方式。
我想补充一点,如果您遇到资源消耗突然增加,那么节流就可以保护您的环境免受停顿;没有限制,BizTalk(像任何其他服务器一样)可能达到无法继续处理并有效“卡住”的程度;限制允许它减速以确保仍在进行处理,直到资源消耗水平(希望)恢复到正常水平;
出于这个原因,我还建议您考虑为您的环境配置一些限制,其值必须根据您的情况进行调整