Build/Test Issues

Liveness extended with enabled timing

Started by Boris Letocha on 10,957 views

This test should pass, but it is not in 1.37b with default settings.

using System;
using NUnit.Framework;

namespace ClassLibrary1
{
[TestFixture]
public class Class1
{
[Test]
public void Test()
{
var weak = new WeakReference(new object());
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.False(weak.IsAlive);
}
}
}
Hi Boris,

Thanks for reporting this. I couldn't get this test to fail when running it locally, so I'm wondering if I might be able to ask some more questions about this issue..

- Is the failure pattern consistent? (i.e. run the test 5-10 times manually or while your system is under load to see if it fails every time)
- What version of the .NET framework are you testing in?
- Does the 'Analyse line execution times' setting have any effect on the result of this test?

Thanks!

Remco
Yes it is consistent. just create c# class library project in VS add NUnit through Nuget, paste this code, enable NCrunch.
I have installed .Net 4.5 CTP, but this runs in VS2010 with selected .Net 4.0
Yes switching off 'Analyse line execution times' is workaround for this problem.
Can you give me any information about the system you're running test on? Is it x64/x86? Multi-core? Hyperthreaded?
It is Multi-core, both hyperthreaded (Work PC) and without hyperthread (Home PC).
CPU architecture in NCrunch settings must be AutoDetect or x86. On x64 it works.
Class Library itself is just Any CPU.
I also submitted bug report if it helps you.
Thanks - I'll see what I can do :)
It's taken a while, but I've finally managed to get to the bottom of this issue after unintentionally reproducing it.

It seems that the .NET 4.5 installer introduces a subtle change in the garbage collection behaviour of the CLR, which affects not only .NET 4.5 but also other installed versions of the framework before it.

The change appears to suppress garbage collection of objects created inside of a try block, even when the garbage collector is being specifically invoked with a GC.Collect(). The objects are instead collected after the try/finally block has been fully executed.

The reasoning behind this isn't clear to me, as objects that are created and go out of scope inside a try block shouldn't really have a reason to exist. I would speculate that this change was introduced as a part of another change to generally improve reliability or make space for more features in the CLR.

Anyway, the change causes some problems for NCrunch when executing tests that are similar to the one you've described above, as NCrunch uses try/finally blocks as part of its performance analysis instrumentation. As described above, to work around the issue, just disable the 'Analyse line execution times' project-level NCrunch configuration setting for the project making use of the WeakReference.

Edited

Fascinating. Just ran into this issue and have switched off the setting as advised. Thanks! And well done getting to the bottom of it.

Post a reply

Log in to reply.