I have a GC testing application that uses System.Reflection.Cache.TypeNameCache. It puts a value into the cache (via RuntimeType.FullName), does a GC (using a new GC), then tries to extract the value from the cache (also using RuntimeType.FullName).
Extracting the value from the cache crashes Rotor as the GC has deleted TypeNameCache.m_cache, TypeNameCache.m_data, etc. It deletes these because m_cache isn't listed as a root by GcScanRoots() or GcScanHandles(). However, I copied this class into my application program file and accessed it directly, instead of through the RuntimeType, and it works fine. Any thoughts on why copying the class would make it behave differently with respect to the GC? Is it some sort of appdomain or namespace issue? Below is my little testing program. thanks, Todd --------------------------------------------------------------- using System; using System.Reflection; public class Sixteen { public int v1; public int v2; public int v3; public int v4; } public class StaticTest { // static public Sixteen m_sixstat; static private StaticTest m_st=null; static public StaticTest GetInstance() { if(m_st == null) { m_st = new StaticTest(); } return m_st; } public Sixteen[] m_sixstat; } internal struct TypeNameStruct { internal int HashKey; internal String TypeName; } internal class TypeNameCache { private static TypeNameCache m_cache = null; private TypeNameStruct[] m_data; internal const int CacheSize = 919; internal TypeNameCache() { m_data = new TypeNameStruct[CacheSize]; } internal static int CalculateHash(int hashKey) { //We know that the bottom two bits of a 32-bit pointer are going to be zero, so //let's not include them in the value that we hash. #if WIN32 return unchecked((int)((((uint)(int)hashKey)>>2)%(uint)CacheSize)); #else return unchecked((int)((((ulong)(long)hashKey)>>3)%(ulong)CacheSize)); #endif } internal String GetTypeName(int hashKey) { int iPos = CalculateHash(hashKey); TypeNameStruct t; t.HashKey = m_data[iPos].HashKey; t.TypeName = m_data[iPos].TypeName; if (t.HashKey==hashKey && m_data[iPos].HashKey==t.HashKey) { return t.TypeName; } return null; } internal void AddValue(int hashKey, String typeName) { int iPos = CalculateHash(hashKey); lock(typeof(TypeNameCache)) { m_data[iPos].HashKey = 0; //Invalidate the bucket. m_data[iPos].TypeName = typeName; //Set the type name. m_data[iPos].HashKey = hashKey; //Revalidate the bucket. } } internal static TypeNameCache GetCache() { if (m_cache==null) { lock (typeof(TypeNameCache)) { if (m_cache==null) { m_cache = new TypeNameCache(); } } } return m_cache; } } public class Test { public static void Main() { System.Console.WriteLine("Starting GC tester"); StaticTest st1 = StaticTest.GetInstance(); st1.m_sixstat = new Sixteen[5]; // Uncomment the following line and the other commented line below // and the program will crash when using my GC. // System.Console.WriteLine(st1.m_sixstat.GetType().FullName); TypeNameCache tnc = TypeNameCache.GetCache(); String s = "blah blah"; tnc.AddValue(13,s); st1.m_sixstat[0] = new Sixteen(); st1.m_sixstat[0].v1 = 7; st1.m_sixstat[0].v2 = 11; st1.m_sixstat[0].v3 = 13; st1.m_sixstat[0].v4 = 17; st1.m_sixstat[1] = new Sixteen(); st1.m_sixstat[2] = new Sixteen(); st1.m_sixstat[3] = new Sixteen(); System.Console.WriteLine(st1.m_sixstat[0].v1); System.Console.WriteLine(st1.m_sixstat[0].v2); System.Console.WriteLine(st1.m_sixstat[0].v3); System.Console.WriteLine(st1.m_sixstat[0].v4); GC.Collect(); st1 = StaticTest.GetInstance(); System.Console.WriteLine(st1.m_sixstat[0].v1); tnc = TypeNameCache.GetCache(); s = tnc.GetTypeName(13); System.Console.WriteLine(s); // Uncomment the following line and the other commented line above // and the program will crash when using my GC. // System.Console.WriteLine(st1.m_sixstat.GetType().FullName); System.Console.WriteLine("Finished GC tester"); } } =================================== This list is hosted by DevelopMentorŪ http://www.develop.com NEW! ASP.NET courses you may be interested in: 2 Days of ASP.NET, 29 Sept 2003, in Redmond http://www.develop.com/courses/2daspdotnet Guerrilla ASP.NET, 13 Oct 2003, in Boston http://www.develop.com/courses/gaspdotnet View archives and manage your subscription(s) at http://discuss.develop.com