c# - GC Behavior Inconsistent Between 32-bit and 64-bit Applications -


i have noticed inconsistent behavior gc when compiling console applications under both 32-bit , 64-bit in .net 4.0 using vs 2013.

consider following code:

class test {     public static bool finalized = false;     ~test()     {         finalized = true;     } } 

and in main() ...

var t = new test(); t = null; gc.collect(); gc.waitforpendingfinalizers(); if (!test.finalized)     throw new exception("oops!"); 

when running in 64-bit (debug) mode works every time without fail; however, running in 32-bit mode cannot force object collected (even if create more objects , wait period of time, have tried).

does have ideas why is? it's causing me trouble when trying debug code must deal releasing unmanaged proxy data 32-bit version of assemblies. there's lot of objects in 32-bit mode sit there until long time later (no in 64-bit).

i'm trying debug in 32-bit mode, finalizers not getting called (at least, not force). objects sit there , never collected (i can see weak references still having value). in 64-bit mode, weak references cleared expected, , finalizers called.

note: though code above on small scale, have noticed in 32-bit mode many more objects stuck in gc until more objects created later (even when "collect" , "waitforpendingfinalizers" called). never case in 64-bit mode. have 1 user wondering why many objects not getting collected, caused me investigate, found out seems work better in 64-bit mode 32. trying understand why.

edit: here better code show differences:

class program {     class test     {         public static bool finalized = false;         public int id;         public test(int id)         {             id = id;         }         ~test()         { // <= put breakpoint here             finalized = true;             console.writeline("test " + id + " finalized.");         }     }      static list<weakreference> weakreferences = new list<weakreference>();      public static bool isnet45ornewer()     {         // class "reflectioncontext" exists .net 4.5 onwards.         return type.gettype("system.reflection.reflectioncontext", false) != null;     }      static void main(string[] args)     {         console.writeline("is 4.5 or newer: " + isnet45ornewer());         console.writeline("intptr: " + intptr.size + environment.newline);          console.writeline("creating objects ...");          (var = 0; < 10; ++i)             weakreferences.add(new weakreference(new test(i)));          console.writeline("triggering collect ...");         gc.collect();          console.writeline("triggering finalizers ..." + environment.newline);         gc.waitforpendingfinalizers();          console.writeline(environment.newline + "checking objects still not finalized ...");          bool ok = true;          (var = 0; < 10; ++i)             if (weakreferences[i].isalive)             {                 var test = (test)weakreferences[i].target;                 if (test != null)                     console.writeline("weak references still exist test " + test.id + ".");                 ok = false;             }          if (ok)             console.writeline("all test objects collected , finalized.");          console.writeline(environment.newline + "creating more objects ...");          (var = 0; < 10; ++i)             weakreferences.add(new weakreference(new test(i)));          console.writeline("triggering collect ...");         gc.collect();          console.writeline("triggering finalizers ..." + environment.newline);         gc.waitforpendingfinalizers();          console.writeline(environment.newline + "checking objects still not finalized ...");          ok = true;          (var = 0; < 10; ++i)             if (weakreferences[i].isalive)             {                 var test = (test)weakreferences[i].target;                 if (test != null)                     console.writeline("weak references still exist test " + test.id + ".");                 ok = false;             }          if (ok)             console.writeline("all test objects collected , finalized.");          console.writeline(environment.newline + "done.");          console.readkey();     } } 

it works in 64-bit, not in 32-bit. on system, "test #9" never gets collected (a weak reference remains), after creating more objects, , trying second time.

fyi: main reason asking question because have \gctest option in console test garbage collection between v8.net , underlying v8 engine on native side. works in 64-bit, not 32.

no repro on vs2013 + .net 4.5 on x86 , x64:

class program {     class test     {         public readonly int i;          public test(int i)         {             = i;         }          ~test()         {             console.writeline("finalizer " + i);         }     }      static void tester()     {         var t = new test(1);     }      public static bool isnet45ornewer()     {         // class "reflectioncontext" exists .net 4.5 onwards.         return type.gettype("system.reflection.reflectioncontext", false) != null;     }      static void main(string[] args)     {         console.writeline("is 4.5 or newer: " + isnet45ornewer());         console.writeline("intptr: " + intptr.size);          var t = new test(2);         t = null;          new test(3);          tester();          console.writeline("pre gc");         gc.collect();         gc.waitforpendingfinalizers();         console.writeline("post gc");          console.readkey();     } } 

note (as noticed @sriram sakthivel), there "ghost" copies of variable around, have lifespan extended until end of method (when compile code in debug mode or have debugger attached (f5 instead of ctrl+f5), lifespan of variables extended until end of method ease debugging)

for example object initialization (when new foo { = 5 }) creates hidden local variable.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -