asp.net - CaliEventHandlerDelegateProxy 泄漏

标签 asp.net azure memory-leaks redis virtual-machine

我们的网站出现问题,看似随机(每天左右,最多每 7-10 天一次),网站就会变得没有响应。

我们在 Azure 上有两个 Web 服务器,并且使用 Redis。

我已经成功运行 DotNetMemory 并在崩溃时捕获它,并且我观察到在事件处理程序泄漏下有两个项目在网站停止工作之前似乎增加了数千个。这两项是 CaliEventHandlerDelegateProxyArglessEventHandlerProxy。一旦站点崩溃,我们会收到大量 Redis 异常,无法连接到 Redis 服务器。根据 Azure 门户,我们的 Redis 服务器负载在高峰时段从未超过 10%,并且我们正在遵循所有最佳实践。

我花了很长时间浏览我们的网站,确保没有明显的内存泄漏,并修补了一些未被注意到的案例。有趣的是,这些似乎稍微提高了网站的稳定性。我们检查过的事情:

  • 所有 iDisposable 对象现在都包装在 using block 中(我们之前严格执行过此操作,但我们确实发现了一些未正确处理的对象)
  • 事件处理程序已取消订阅 - 我们的代码库中很少
  • 我们大量使用 WebUserControls。每个页面都将当前母版页作为参数传入。我们已经删除了对此的依赖,因为我们认为它可能导致 GC 不收集页面

我们的最新问题是,当 Web 服务器运行良好,但随后我们运行 DotNetMemory 并将其附加到 w3wp.exe 进程时,它会导致 CaliEventHandlerDelegateProxyArglessEventHandlerProxy 事件泄漏量迅速增加,直至网站崩溃!因此,只需运行 DotNetMemory 即可重现崩溃。这是我们看到的屏幕截图:

enter image description here

我现在不知所措,我相信我已经用尽了代码库中内存泄漏的所有可能性,我们的“解决方案”是让应用程序池每隔几个小时回收一次,以确保安全。

我们甚至尝试将 Redis 升级到高级层,甚至将网络服务器上的所有驱动器升级为 SSD,看看它是否能帮助解决看似没有的问题。

谁能解释一下可能导致这些问题的原因吗?

最佳答案

All iDisposable objects are now wrapped in using blocks (we did this strictly before but we did find a few not disposed properly)

在没有任何相关信息的情况下,我们不能对崩溃说太多,但我对此有一些猜测。 我看到 10 000 (!) 未处置的对象由终结队列处理。让我们从它们开始,找到所有这些并在您的应用程序中添加 Dispose 调用。 另外,我建议检查您的应用程序使用了多少系统句柄。操作系统对句柄数量有限制,如果超过,则无法创建更多文件句柄、网络套接字等。我特别推荐它,因为未处理的对象数量很多。

此外,如果您在访问 Redis 时超时,请获取性能分析器并查看原因。我建议使用 JetBrains dotTrace 并使用 TIMELINE 模式来获取应用程序的配置文件,它将显示线程休眠、线程争用以及更多信息,这些信息将帮助您找到问题根源。您可以使用命令行工具来获取配置文件数据,以免在服务器端安装GUI应用程序。

it causes the CaliEventHandlerDelegateProxy and ArglessEventHandlerProxy event leaks to increase rapidly

dotMemory 不会更改您的应用程序代码,也不会在分析进程中分配任何托管对象。 Microsoft Profiling API 将一个 dll(用 C++ 编写)注入(inject)到分析过程中,它是 dotMemory 的一部分,名为 Profilng Core,扮演“服务器”的角色(其中用 C# 编写的独立 dotMemory 是客户端)。分析核心在将收集的数据发送到客户端之前对其进行一些处理,它需要一些内存,当然,这些内存是在分析过程的地址空间中分配的,但它不会影响托管内存。

内存分析可能会影响应用程序的性能。例如,当应用程序进行分析时,分析 API 会禁用并发 GC,或者内存分配数据收集会显着降低应用程序的速度。 为什么您认为 CaliEventHandlerDelegateProxy 和 ArglessEventHandlerProxy 仅在 dotMemory 分析下分配?您能描述一下您是如何探索这一点的吗?

Event handlers are unsubscribed - there are very few in our code base

dotMemory 将事件处理程序报告为泄漏,这意味着只有一个对它的引用 - 从事件源,无法取消订阅此事件。检查所有这些泄漏,通过查看代码找到您的泄漏是如何发生的。无论如何,这些对象只保留了 110.3 KB,为什么您认为您的网站会因为它们而崩溃?

I'm at a loss now, I believe I've exhausted all possibilities of memory leaks in our code base

在内存消耗增长的一段时间内拍几张快照,打开其中一些快照的完整比较,查看所有不应该存活的存活对象,找出它们存活的原因。这是证明您的应用没有内存泄漏的唯一方法,查看代码并不能证明这一点,抱歉。

希望如果您执行我建议您执行的所有事件(性能分析、完整快照和快照比较调查,不仅仅是检查 View ,检查为什么存在大量未处理对象),您将找到并解决根本问题.

关于asp.net - CaliEventHandlerDelegateProxy 泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59984317/

相关文章:

c# - 从 ASP.NET 中的另一个源获取字符串形式的发布数据

c# - 请求被中止 : Could not create SSL/TLS secure channel

c# - 在 ASP.NET 的上下文中,为什么 Task.Run(...).Result 在调用异步方法时不会死锁?

azure - 为什么在 azure 应用程序服务中进行插槽交换后应用程序洞察不起作用?

插入到 Azure SQL 表时触发 Azure 事件网格自定义主题

c# - 自动改变字体大小

azure - 如何在 Azure AD B2C 中登录期间禁用 MFA

c - 内存泄漏示例的问题

c - 我是否有可能知道我是否已在 C 中正确清理?

c++ - SDL/OpenGL 双缓冲内存泄漏