WeakReference with Enabled profiler problem

7 posts, 0 answers
  1. Alexander
    Alexander avatar
    17 posts
    Member since:
    May 2012

    Posted 26 Sep 2013 Link to this post

    Hello Telerik,

    I've found a problem with WeakReference and JustMock profiler. Here is a simple test which fails if profiler is enabled and pass if profiler is disabled:

    [TestMethod]
            public void WeakRefTest()
            {
                var obj = new object();
                var weakRef = new WeakReference(obj);
                obj = null;
                GC.Collect();

                Assert.IsNull(weakRef.Target);
            }

    I'm using latest development build of JustMock. Is it expected behavior or a bug in profiler?

    Thank you,
    Alex
  2. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 26 Sep 2013 Link to this post

    Hi Alexander,

    To make your test work, do any of the following:
    • place the [DisableAutomaticRepositoryReset] attribute on your test method, or
    • move it to a test assembly that doesn't reference JustMock, or
    • run the test only in Release, or
    • run the test only in x64.

    It is not a bug in JustMock, but rather in the way GC handles references on the stack.

    Try the following: wrap the body of the test in a try/finally block (leave the finally block empty), build in Debug, disable the JustMock profiler and run the test again. The test will fail. All you did was wrap the test in a no-op try/finally, yet the test fails! Now, build the test project in Release and run it again - the test will succeed!

    What happens is that even though you have "obj = null" in your code, the JIT artificially extends the lifetime of the object assigned to it to go to the end of the method (end of the variable's scope). This effect is due to a combination of factors: the JIT sees that the assembly is built with Debug on, so it extends lifetimes for easier debugging; the GC sees the lifetime extensions and decides that this object should not yet be collected.

    For an additional mind-twist, remove the "obj = null" line and run the test in Release - the test will still succeed! The JIT doesn't actually care whether you nullify your local variables like that or not - it's smart enough to deduce that you never use the obj variable after the point of calling "GC.Collect()" so it can tell the GC that that variable is no longer a root.

    By the way, you won't observe this behavior if you run in x64. That's because the x64 JIT is totally different from the x86 JIT.

    In short, you cannot rely on the behavior of the GC with respect to local variables because it is an implementation detail and often behaves unintuitively. Here's an answer to this question given by an expert. Here's another one.

    For further information, read the documentation of DisableAutomaticRepositoryResetAttribute.

    Regards,
    Stefan
    Telerik
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  3. DevCraft R3 2016 release webinar banner
  4. Alexander
    Alexander avatar
    17 posts
    Member since:
    May 2012

    Posted 26 Sep 2013 Link to this post

    Thank you, Stefan

    Especially for detailed answer. It is still not clear for me why it works without profiler and not working with it. But anyway, now I have more than one solution for the problem.

    Have a nice day,
    Thank again,
    Alex
  5. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 26 Sep 2013 Link to this post

    Hi Alexander,

    The profiler makes the test fail, because it wraps the bodies of all [TestMethod] methods in a try/finally block (for internal bookkeeping). This change doesn't affect the correctness of your code, but changes the way the GC behaves in subtle ways.

    Regards,
    Stefan
    Telerik
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  6. Alexander
    Alexander avatar
    17 posts
    Member since:
    May 2012

    Posted 26 Sep 2013 Link to this post

    Now its clear for me,

    Thank you again!
  7. Alexander
    Alexander avatar
    17 posts
    Member since:
    May 2012

    Posted 26 Sep 2013 Link to this post

    Hm, cannot find anything about DisableAutomaticRepositoryReset attribute.
    Where can I find it?

    Unfortunately, Release and x64 seems to be not an option for me.
    Most strange thing is the same test was working several weeks ago.

    Thanks,
    Alex
  8. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 26 Sep 2013 Link to this post

    Hello Alexander,

    I'm sorry for the mix-up. The attribute and its accompanying documentation will be made available in the internal build due today or tomorrow.

    This behavior is pretty recent - implemented first in JustMock Q2 SP2 (2013.2.724).

    Regards,
    Stefan
    Telerik
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
Back to Top
DevCraft R3 2016 release webinar banner