Skip to content

Commit

Permalink
Fix memory leak on TaskManager due to continuous growth of knownHashe…
Browse files Browse the repository at this point in the history
…s (2.x) (#865)

* First draft with knownhashes as dictionary

* Remove first known hash - searching by value

* Parameters calibration and code style

* Fix tasks removal and limits

* Avoid the same hash value

* With fifo (#867)

* Update TaskManager.cs

* Update FIFOSet.cs

* Remove lock

* Update FIFOSet.cs

* Rename
  • Loading branch information
vncoelho committed Jun 26, 2019
1 parent 1e2c6c6 commit d993e4d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
21 changes: 20 additions & 1 deletion neo/IO/Caching/FIFOSet.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

namespace Neo.IO.Caching
{
internal class FIFOSet<T> where T : IEquatable<T>
internal class FIFOSet<T> : IEnumerable<T> where T : IEquatable<T>
{
private readonly int maxCapacity;
private readonly int removeCount;
Expand Down Expand Up @@ -37,5 +40,21 @@ public bool Add(T item)
dictionary.Add(item, null);
return true;
}

public void ExceptWith(IEnumerable<UInt256> hashes)
{
foreach (var hash in hashes)
{
dictionary.Remove(hash);
}
}

public IEnumerator<T> GetEnumerator()
{
var entries = dictionary.Values.Cast<T>().ToArray();
foreach (var entry in entries) yield return entry;
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}
10 changes: 9 additions & 1 deletion neo/Network/P2P/TaskManager.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Akka.Actor;
using Akka.Configuration;
using Neo.IO.Actors;
using Neo.IO.Caching;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using System;
Expand All @@ -24,7 +25,14 @@ private class Timer { }

private readonly NeoSystem system;
private const int MaxConncurrentTasks = 3;
private readonly HashSet<UInt256> knownHashes = new HashSet<UInt256>();

/// <summary>
/// Max GetBlocks and Headers are limmited to 500 each
/// Blockchain.Singleton.MemPool.Capacity * 2 was the same value used in ProtocolHandler
/// </summary>
private static readonly int MaxCachedHashes = Blockchain.Singleton.MemPool.Capacity * 2;
private readonly FIFOSet<UInt256> knownHashes = new FIFOSet<UInt256>(MaxCachedHashes);

private readonly Dictionary<UInt256, int> globalTasks = new Dictionary<UInt256, int>();
private readonly Dictionary<IActorRef, TaskSession> sessions = new Dictionary<IActorRef, TaskSession>();
private readonly ICancelable timer = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(TimerInterval, TimerInterval, Context.Self, new Timer(), ActorRefs.NoSender);
Expand Down

0 comments on commit d993e4d

Please sign in to comment.