.net - ReactiveUI ObservableAsPropertyHelper/Reactive Extensions 内存泄漏?

标签 .net memory-leaks system.reactive reactiveui

我注意到在我使用 ReactiveUI 的 .NET 3.5 应用程序中,我有一个明显的内存泄漏,它似乎起源于 ObservableAsPropertyHelper。我创建了一个测试项目来演示它 here .

似乎由一个简单的 ObservableAsPropertyHelper 计算的属性触发的每个更改通知都会泄漏内存。泄漏似乎源于 Reactive Extensions,而不是直接在 ReactiveUI 中,但是我对 OAPH 的使用非常简单,我想知道是否有人遇到过这种情况或可能有建议的修复程序。

内存泄漏的严重程度在 .NET 3.5(RxUI 2.4、Rx 1.1)和 .NET 4.0(RxUI 4.2、Rx 2.0.3)之间有所不同。 .NET 3.5 中属性的每次更新都更接近线性。但是,泄漏仍然存在于 .NET 4.0 中。

我已经上传了测试项目和一些分析器图像,用于我的 .NET 3.5 和 .NET 4.0 测试 session 与测试应用程序,here .

您可以在图像中看到对象图是不同的,因此我们可能完全在谈论两种不同的泄漏。在 4.0 session (40_RetentionGraph.png) 中,您可以看到分配最多的对象是 Ints(我的 OAPH 属性的类型)和 ConcurrentQueue。那里似乎存在某种循环引用问题。您还可以在 40_IntsAllocatedGCRootGrows.png 中看到实例与 GC 根的距离在增长。

在3.5版本(我最关心的)中,可以看到(35_Summary.png)分配最多的对象是Action和ScheduledObserver。对象图有点复杂,与 40 版本完全不同。

我已审核 this discussion但还没有找到直接的答案:我的情况是,对 OAPH 的更新非常简单。对此泄漏的可能解决方案的任何见解表示赞赏。

最佳答案

您尚未指定调度程序,因此默认情况下 RxUI 将用于 DispatcherScheduler。由于您的应用程序是控制台应用程序,因此没有正在运行的 Dispatcher。所有的内存都被 OnNext 的排队消耗掉了,没有什么可以运行它们。

您可能会搞砸启动调度程序并为其提供帧以运行(WPF 应用程序会为您执行此操作),或者为了进行测试,只需更改 ReactiveTester 构造函数即可:

public ReactiveTester()
{
  _Total = this.WhenAny(x => x.A, x => x.B, (a, b) => a.Value + b.Value)
               .ToProperty(this, x => x.Total);
}

对此:
public ReactiveTester()
{
  _Total = this.WhenAny(x => x.A, x => x.B, (a, b) => a.Value + b.Value)
               .ToProperty(this, x => x.Total, 0, Scheduler.CurrentThread);
}

一切都将是美好的。

关于.net - ReactiveUI ObservableAsPropertyHelper/Reactive Extensions 内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16668399/

相关文章:

c# - MSIL 是否与 .NET 中的托管代码相同?

c# - .net core/.net 标准项目之间的 Resharper 引用错误

c# - 如何限制用户只能使用 Linq To SQL 编辑数据?

c# - 获取 url 的主要部分,包括虚拟目录

ios - 这是否是内存问题

system.reactive - 有没有办法在定义后以声明方式将更新推送到 observable?

c# - react 性扩展 : Stop an observable from returning before the tasks it has spun off have finished?

c# - 如何将 Rx Observable 与通用 EventHandler<T> 一起使用?

c++ - Eigen 稀疏矩阵乘法的内存泄漏

javascript - 如果不在 switch case 中声明 block 范围,是否会导致内存泄漏? (ESLint 无案例声明)