[Mono-bugs] [Bug 384723] New: Dictionary prevents GC
bugzilla_noreply at novell.com
bugzilla_noreply at novell.com
Tue Apr 29 07:51:18 EDT 2008
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 at lists.ximian.com
ReportedBy: jesjones at mindspring.com
QAContact: mono-bugs at 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.
More information about the mono-bugs
mailing list