4

I wanted to do this in order to test my code. I suppose I could make another wrapper around the weakreference object, but would prefer to work directly to simulate the original object getting reclaimed.

This is the code that I have so far

 var myString = "someString";
 var myStringRef = new WeakReference(myString);
 myString = null;
 GC.Collect();
 Assert.IsFalse(myStringRef.IsAlive) //I want this to pass, but it failed. IsAlive is still true.

What can I do to force the last line above to not fail (ie. !IsAlive)

I have some framework logic that does housekeeping based on the status of the weakreference. I want to be able to test that logic, to do so, I need to be able to change the weakreference state at will - so how can I do this?

Alwyn
  • 8,079
  • 12
  • 59
  • 107
  • Not a exact duplicate, but a [similar question](http://stackoverflow.com/questions/208387/weakreference-bug) has been asked. – D Stanley Aug 22 '13 at 18:03

4 Answers4

3

I wonder if this has something to due with the fact that strings are interned, because the following test passes:

    var myObject = new object();
    var myObjectRef = new WeakReference(myObject);
    myObject = null;
    GC.Collect();
    Assert.IsFalse(myObjectRef.IsAlive);
qxn
  • 17,162
  • 3
  • 49
  • 72
2

Literal strings are interned by default, so despite the fact that you null myString the instance is still rooted by the intern table.

Please see my answer to this question for details about how interning is handled.

Community
  • 1
  • 1
Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
2

Instead of hardcoding the string into the source file, read it in via an external source. For example, you can create a TestStrings.txt file where your string(s) are placed and use this.

string myString = File.ReadAllText(@"TestStrings.txt");         

var myStringRef = new WeakReference(myString);
myString = null;

GC.Collect();
Assert.IsFalse(myStringRef.IsAlive);

This should return false. As mentioned in the other answer, this is indeed due to string interning.

By reading the text from an external source the strings won't be interned here which seems to be what you want for this test. (You can check if the string is interned by using String.IsInterned method).

keyboardP
  • 68,824
  • 13
  • 156
  • 205
0

to do so, I need to be able to change the weakreference state at will

You could build an abstraction around WeakReference and make that testable (using an interface or a "test mode" which allows you to change the value returned by IsAlive).

usr
  • 168,620
  • 35
  • 240
  • 369