6

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

似乎由一个简单的 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 测试会话与测试应用程序上传了测试项目和一些分析器图像,这里

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

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

我已经查看了这个讨论,但没有找到直接的答案:我的情况是,对 OAPH 进行非常简单的更新。任何有关此泄漏的可能解决方案的见解都值得赞赏。

4

1 回答 1

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);
}

一切都会变得美好。

于 2013-05-21T18:44:47.587 回答