使用NSubstitute接口在循环中发生内存泄漏?

时间:2018-09-20 15:08:35

标签: nsubstitute

如果运行以下程序,我会发现Windows任务管理器中的可用内存迅速减少为零。禁止在循环中使用NSubstitute吗?

using System;
using NSubstitute;
using System.Threading;

namespace NSubstituteMemoryLeaks
{
    class Program
    {
        static void Main(string[] args)
        {
            IConfig config = Substitute.For<IConfig>();
            config.Value.Returns(0);

            Thread th = new Thread(() => {
                while (true)
                {
                    int val = config.Value;
                }
            });
            th.IsBackground = true;
            th.Start();

            Console.WriteLine("Press ENTER to stop...");
            Console.ReadLine();
        }
    }

    public interface IConfig
    {
        int Value { get; set; }
    }
}

2 个答案:

答案 0 :(得分:1)

模拟生成对象。问题在于程序会在短时间内创建那些对象,并且没有给Garbage Collector足够的时间来收集对象。

它不特定于NSubstitute。您也可以在Moq中看到相同的行为。

您可以通过显式调用GC.Collect();来解决。

Task.Run(() =>
{
    while (true)
    {
        int val = config.Value;
        GC.Collect();
    }
});

有优缺点。您可能想在实现之前先阅读When to call GC.Collect()

答案 1 :(得分:1)

NSubstitute记录对替代项的所有调用,因此,如果您在无限循环中调用替代项,最终将耗尽可用内存。 (如果在10,000次循环迭代后调用config.ReceivedCalls(),则应该在该列表中看到10,000个条目。)

如果您在循环中定期调用config.ClearReceivedCalls(),可能会有所帮助。

如果您有一个有界循环,这应该不成问题;一旦替代品不再使用,内存将被清除,GC会清除它。