我正在使用rx distinct运算符根据长时间运行的进程中的某个键过滤外部数据流。
这会导致内存泄漏吗?假设将收到许多不同的密钥。 rx distinct运算符如何跟踪以前收到的密钥?
我应该将groupbyuntil与持续时间选择器一起使用吗?
答案 0 :(得分:5)
Observable.Distinct
在内部使用HashSet
。内存使用量大致与遇到的不同键的数量成正比。 (AFAIK约30 * n字节)
GroupByUntil
做的事情与Distinct
完全不同。
GroupByUntil
(井)组,而Distinct
过滤流的元素。
不确定预期用途,但如果您只想过滤连续相同的元素,则需要Observable.DistinctUntilChanged
,其内存占用量与键数无关。
答案 1 :(得分:1)
这可能是一个有争议的策略,但如果您担心不同的密钥累积,并且如果有一个时间点可以安全地重置,您可以使用Observable.Switch引入重置策略。例如,我们有一个场景,每天都会重置“世界状况”,因此我们可以每天重置不同的可观察量。
Observable.Create<MyPoco>(
observer =>
{
var distinctPocos = new BehaviorSubject<IObservable<MyPoco>>(pocos.Distinct(x => x.Id));
var timerSubscription =
Observable.Timer(
new DateTimeOffset(DateTime.UtcNow.Date.AddDays(1)),
TimeSpan.FromDays(1),
schedulerService.Default).Subscribe(
t =>
{
Log.Info("Daily reset - resetting distinct subscription.");
distinctPocos.OnNext(pocos.Distinct(x => x.Id));
});
var pocoSubscription = distinctPocos.Switch().Subscribe(observer);
return new CompositeDisposable(timerSubscription, pocoSubscription);
});
但是,我确实倾向于同意James World上面关于使用内存分析器进行测试的评论,以便在引入可能不必要的复杂性之前检查内存确实是一个问题。如果您正在累积32位整数作为密钥,那么在大多数平台上遇到内存问题之前,您将拥有数百万个唯一项。例如。 262144 32位int键占用1兆字节。可能是您在此时间之前很久重置了该过程,具体取决于您的方案。