Daily Usage Issues

System.OutOfMemoryException in churn mode

Started by spolonski on 2,235 views

Hi Remco,

An System.OutOfMemoryException exception occurs while executing the following test in churn mode from VS:

Ncrunch Version: 4.15.0.4
Build process CPU architecture: x64
Use CPU architecture: AutoDetect
Engine hosting strategy: x64SatelliteProcess
Solution Configuration: Release
Solution Platform: x86


Stacktrace:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, Object[] args)
   at nCrunch.Module.NUnit3.Integration.FrameworkController.RunTests(INUnit3CallbackHandler handler, String filter)
   at nCrunch.Module.NUnit3.Integration.NUnit3FrameworkInteractor.<>c__DisplayClass11_1.<RunTests>b__3()
   at nCrunch.Common.PerformanceTracking.PerfTracker.TrackUnreliableActivity(String name, Action activity)
   at nCrunch.Common.PerformanceTracking.PerfTracker.TryTrackUnreliableActivity(String name, Action activity)
   at nCrunch.Module.NUnit3.Integration.NUnit3FrameworkInteractor.<>c__DisplayClass11_0.<RunTests>b__1()
   at nCrunch.TestExecution.TimeoutEnforcement.AbortingTimeoutEnforcer.ExecuteWithPossibleEnforcement(Action codeToExecute)
   at nCrunch.TestExecution.TimeoutEnforcement.AbortingWithTerminationFallbackTimeoutEnforcer..()
   at nCrunch.TestExecution.TimeoutEnforcement.TerminatingTimeoutEnforcer.ExecuteWithPossibleEnforcement(Action codeToExecute)
   at nCrunch.TestExecution.TimeoutEnforcement.AbortingWithTerminationFallbackTimeoutEnforcer.ExecuteWithPossibleEnforcement(Action codeToExecute)
   at nCrunch.TestExecution.TestExecutionMonitor.PerformMonitoredTestExecution(Action testExecutionAction)
   at nCrunch.Module.NUnit3.Integration.NUnit3FrameworkInteractor.RunTests(TestEnvironmentConfig environmentConfig, TestTaskOutput output, TestExecutionMapSet testMapSet, TestExecutionParameters parameters, Int32 defaultTimeout, IIpcMessageProcessor ipcMessageProcessor)
   at nCrunch.Module.NUnit3.Integration.NUnit3FrameworkRuntimeEnvironment.RunTests(TestTaskOutput output, TestExecutionMapSet testMapSet, TestExecutionParameters parameters, IIpcMessageProcessor ipcMessageProcessor)
   at nCrunch.TestExecution.TestRunnerThread.()


Unit:

using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;

namespace My.Extensions
{
    public static class TaskExtensions
    {
        public static async Task<T> AwaitWithTimeout<T>(this Task<T> task, int timeout, Action error)
        {
            if (await Task.WhenAny(task, Task.Delay(timeout)).ConfigureAwait(false) == task)
            {
                return await task.ConfigureAwait(false);
            }

            error();
            return  default(T);
    }
}



Test:

using System;
using System.Threading.Tasks;
using FluentAssertions;
using NUnit.Framework;
using My.Extensions;

namespace My.Test
{
    [TestFixture]
    public class TaskExtensionsTest
    {
        [TestCase(50, 500, false, 1)]
        public async Task Task_Should_Terminate_If_Timeout_Is_Expired_Async(int time, int timeout, bool shouldExpired, int shouldValue)
        {
            var timeStart = HighResolutionTimer.Now();
            var t = CreateResultWithDelayAsync(time, 1);
            var value =  await t.AwaitWithTimeout(timeout, () => { }).ConfigureAwait(false);
            TestContext.WriteLine($"Duration = {new TimeSpan(HighResolutionTimer.Now() - timeStart)}");
            value.Should().Be(shouldValue);
        }

        private async Task<int> CreateResultWithDelayAsync(int delay, int result)
        {
            await Task.Delay(delay);
            return result;
        }
    }


Hi, thanks for sharing this issue.

Do you still experience this problem when running the test with the 'Test Process Memory Limit' NCrunch config setting set to something sensible? My guess here would be that accumulated memory in the process is pushing it past the x86 2GB memory limit. Setting the test to run under x64 might give you more space, but a memory limit would be a more sensible option.
Remco wrote:Hi, thanks for sharing this issue.

Do you still experience this problem when running the test with the 'Test Process Memory Limit' NCrunch config setting set to something sensible? My guess here would be that accumulated memory in the process is pushing it past the x86 2GB memory limit. Setting the test to run under x64 might give you more space, but a memory limit would be a more sensible option.


Thanks. It was just what the doctor ordered. IMHO It should be set in default to something like 500MB.
PS: I set it to 130MB.
Remco wrote:My guess here would be that accumulated memory in the process is pushing it past the x86 2GB memory limit.


Actually memory limit in x86 for .Net is about 600MB- 700MB :(
spolonski wrote:
Actually memory limit in x86 for .Net is about 600MB- 700MB :(


Usually it's a 2GB heap minus fragmentation in the process. If you have code allocating large objects with high frequency, this causes more fragmentation. Older versions of .NET are worse. If you're getting OOM at 700MB, this suggests some serious fragmentation. Setting your test projects to run under x64 might not be a terrible idea (assuming your machine has sufficient memory).

Post a reply

Log in to reply.