https://bugzilla.novell.com/show_bug.cgi?id=384723
Summary: Dictionary prevents GC Product: Mono: Class Libraries Version: 1.9.0 Platform: Other OS/Version: Mac OS X 10.4 Status: NEW Severity: Major Priority: P5 - None Component: System AssignedTo: mono-bugs@lists.ximian.com ReportedBy: [EMAIL PROTECTED] QAContact: mono-bugs@lists.ximian.com Found By: --- Unlike System.Collections.Generic.List System.Collections.Generic.Dictionary does not zero out elements when they are removed or when the collection is cleared. Instead Dictionary merely marks the corresponding slot as unused. This is pretty bad because it means the default conservative garbage collector in mono 1.9 will think that there is still a reference to the cleared objects and prevent them from being collected. They will only be collected when the slot is reused. Here's a test case: // compile with: gmcs -out:app.exe -target:exe Dictionary.cs using System; using System.Collections.Generic; using System.Threading; // With mono 1.9 I get the following output: // removed an item from the dict, but delta is 0 // cleared the dict, but delta is 0 internal class Item { ~Item() { --ms_instanceCount; } public Item() { ++ms_instanceCount; } public static int Count { get {return ms_instanceCount;} } private static int ms_instanceCount; } internal class Program { private static void Main() { TestList(); TestDict(); ForceCollect(); MyAssert(Item.Count == 0, "finished but count is " + Item.Count); if (!ms_failed) Console.WriteLine("passed"); } private static void TestList() { List<Item> l = new List<Item>(); int initial = Item.Count; l.Add(new Item()); l.Add(new Item()); l.Add(new Item()); ForceCollect(); MyAssert(Item.Count == initial + 3, "added 3 items to a list, but delta is " + (Item.Count - initial)); initial = Item.Count; l.RemoveAt(0); ForceCollect(); MyAssert(Item.Count == initial - 1, "removed an item from the list, but delta is " + (Item.Count - initial)); initial = Item.Count; l.Clear(); ForceCollect(); MyAssert(Item.Count == initial - 2, "cleared the list, but delta is " + (Item.Count - initial)); } private static void TestDict() { Dictionary<int, Item> d = new Dictionary<int, Item>(); int initial = Item.Count; d.Add(1, new Item()); d.Add(2, new Item()); d.Add(3, new Item()); ForceCollect(); MyAssert(Item.Count == initial + 3, "added 3 items to a dict, but delta is " + (Item.Count - initial)); initial = Item.Count; d.Remove(2); ForceCollect(); MyAssert(Item.Count == initial - 1, "removed an item from the dict, but delta is " + (Item.Count - initial)); initial = Item.Count; d.Clear(); ForceCollect(); MyAssert(Item.Count == initial - 2, "cleared the dict, but delta is " + (Item.Count - initial)); } private static void ForceCollect() { System.GC.Collect(); Thread.Sleep(200); // note that we need to sleep to allow the finalizer thread to kick in } private static void MyAssert(bool p, string s) { if (!p) { Console.WriteLine(s); ms_failed = true; } } private static bool ms_failed; } -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the QA contact for the bug. You are the assignee for the bug. _______________________________________________ mono-bugs maillist - mono-bugs@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-bugs