Akka.net: Memory leak when using Context.WatchWith

Created on 10 Nov 2019  路  3Comments  路  Source: akkadotnet/akka.net

Hi, I encountered a memory leak with Context.WatchWith. Here is a repro code:
``` C#
using System;
using System.Collections.Generic;
using Akka.Actor;

namespace MemoryLeakRepro
{
public class LoadHandler : ReceiveActor
{
private readonly List _subjects;
private readonly ICancelable _cancel;

    public LoadHandler()
    {
        _subjects = new List<IActorRef>();
        _cancel = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(
            initialDelay: TimeSpan.FromSeconds(1),
            interval: TimeSpan.FromSeconds(1),
            receiver: Self,
            message: Iteration.Instance,
            sender: ActorRefs.NoSender);

        Receive<Iteration>(
            _ =>
            {
                // stop actors created on previous iteration
                _subjects.ForEach(Context.Stop);
                _subjects.Clear();

                // create a set of actors and start watching them
                for (var i = 0; i < 10_000; i++)
                {
                    var subject = Context.ActorOf(Props.Create<Subject>());
                    _subjects.Add(subject);
                    Context.WatchWith(subject, new Stopped(subject));
                }
            });

        Receive<Stopped>(_ => { });
    }

    private class Iteration
    {
        public static readonly Iteration Instance = new Iteration();
        private Iteration() { }
    }

    private class Stopped
    {
        public IActorRef ActorRef { get; }

        public Stopped(IActorRef actorRef)
        {
            ActorRef = actorRef;
        }
    }

    private class Subject : ReceiveActor
    {
        // simulate internal state
        private byte[] _state = new byte[1000];
    }

    protected override void PostStop() => _cancel.Cancel();
}

public static class Program
{
    public static void Main(string[] args)
    {
        using (var actorSystem = ActorSystem.Create("repro"))
        {
            actorSystem.ActorOf(Props.Create<LoadHandler>());
            Console.ReadKey();
        }
    }
}

}

```XML
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Akka" Version="1.3.15" />
  </ItemGroup>

</Project>

In my understanding this code should not leak: Subject actor references must be released as soon as LoadHandler processed Stopped message. However, looking at profiler - it doesn't look like this happens:
image
image

I also found a very similar issue in Akka repository which is already fixed, but I don't think this was ported to Akka.NET: https://github.com/akka/akka/issues/26625

akka-actor confirmed bug

Most helpful comment

@AndrewBoklashko fixed - will be released in the next v1.4.0-beta4 release.

All 3 comments

@AndrewBoklashko do you mind creating a PR for this?

@ismaelhamed I would like to do so, but unfortunately I am very limited in time at least by the end of this month. I was able to workaround this by simply using Context.Watch, so this issue is not really a blocker for me.

@AndrewBoklashko fixed - will be released in the next v1.4.0-beta4 release.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Horusiath picture Horusiath  路  5Comments

nvivo picture nvivo  路  6Comments

vasily-kirichenko picture vasily-kirichenko  路  4Comments

netogallo picture netogallo  路  7Comments

jalchr picture jalchr  路  3Comments