ReactiveUI ObservableAsPropertyHelper / Reactive Extensions内存泄漏?

时间:2013-05-21 11:00:27

标签: .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中仍然存在漏洞。

我已经使用测试应用程序here上传了我的.NET 3.5和.NET 4.0测试会话的测试项目和一些探查器图像。

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

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

我已经审核了this discussion但未找到直接答案:我的方案是,对OAPH进行非常简单的更新。任何有关这种泄漏的可能解决方案的见解都表示赞赏。

1 个答案:

答案 0 :(得分:5)

您尚未指定调度程序,因此默认情况下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);
}

一切都会很美好。