G
Guest
I tried a small program, found that some local objects can't be automatically
collected by GC. I tried both in 1.1 and 2.0, get the same result.
Below the program, just try it, you will found that the last 3 objects
didn't been released. Does anyone have some idear on it?
namespace TestMem
{
class Root
{
public Int32 m_ID;
public Root()
{
m_ID = this.GetHashCode();
}
~Root()
{
System.Threading.Monitor.Enter(ObjectMgr.m_list);
ObjectMgr.UnRegister(this);
System.Threading.Monitor.Exit(ObjectMgr.m_list);
}
}
class A : Root
{
}
class B : Root
{
}
class C : Root
{
}
class ObjectMgr
{
static int m_nRegisteredCnt = 0;
static int m_nUnRegCnt = 0;
static public System.Collections.ArrayList m_list = new
System.Collections.ArrayList();
static public void Register(Root obj)
{
System.Threading.Monitor.Enter(m_list);
m_nRegisteredCnt++;
m_list.Add(obj.m_ID);
System.Threading.Monitor.Exit(m_list);
}
static public void UnRegister(Root obj)
{
System.Threading.Monitor.Enter(m_list);
m_nUnRegCnt++;
m_list.Remove(obj.m_ID);
System.Threading.Monitor.Exit(m_list);
}
static public int GetCnt()
{
System.Threading.Monitor.Enter(m_list);
int nCnt = m_list.Count;
System.Threading.Monitor.Exit(m_list);
return nCnt;
}
static public void PrintUnreleasedObjects()
{
System.Threading.Monitor.Enter(m_list);
Console.WriteLine("Registered = {0}, Unregistered={1}",
m_nRegisteredCnt, m_nUnRegCnt);
int nTmp = 0;
foreach (int objID in m_list)
{
nTmp++;
Console.WriteLine("Objects in list, ID = {0}", objID);
if (nTmp >= 10)
break;
}
System.Threading.Monitor.Exit(m_list);
}
}
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10000; i++)
{
A a;
B b;
C c;
a = new A();
b = new B();
c = new C();
a.m_ID = 3 * i;
b.m_ID = 3 * i+1;
c.m_ID = 3 * i+2;
ObjectMgr.Register(a);
ObjectMgr.Register(b);
ObjectMgr.Register(c);
if (i % 100 == 0)
{
Console.WriteLine("i={0}",i);
}
}//
while (ObjectMgr.GetCnt() > 0)
{
Console.WriteLine("There are {0} objects in list",
ObjectMgr.GetCnt());
ObjectMgr.PrintUnreleasedObjects();
System.Threading.Thread.Sleep(5000);
GC.Collect();
}
}
}
}
collected by GC. I tried both in 1.1 and 2.0, get the same result.
Below the program, just try it, you will found that the last 3 objects
didn't been released. Does anyone have some idear on it?
namespace TestMem
{
class Root
{
public Int32 m_ID;
public Root()
{
m_ID = this.GetHashCode();
}
~Root()
{
System.Threading.Monitor.Enter(ObjectMgr.m_list);
ObjectMgr.UnRegister(this);
System.Threading.Monitor.Exit(ObjectMgr.m_list);
}
}
class A : Root
{
}
class B : Root
{
}
class C : Root
{
}
class ObjectMgr
{
static int m_nRegisteredCnt = 0;
static int m_nUnRegCnt = 0;
static public System.Collections.ArrayList m_list = new
System.Collections.ArrayList();
static public void Register(Root obj)
{
System.Threading.Monitor.Enter(m_list);
m_nRegisteredCnt++;
m_list.Add(obj.m_ID);
System.Threading.Monitor.Exit(m_list);
}
static public void UnRegister(Root obj)
{
System.Threading.Monitor.Enter(m_list);
m_nUnRegCnt++;
m_list.Remove(obj.m_ID);
System.Threading.Monitor.Exit(m_list);
}
static public int GetCnt()
{
System.Threading.Monitor.Enter(m_list);
int nCnt = m_list.Count;
System.Threading.Monitor.Exit(m_list);
return nCnt;
}
static public void PrintUnreleasedObjects()
{
System.Threading.Monitor.Enter(m_list);
Console.WriteLine("Registered = {0}, Unregistered={1}",
m_nRegisteredCnt, m_nUnRegCnt);
int nTmp = 0;
foreach (int objID in m_list)
{
nTmp++;
Console.WriteLine("Objects in list, ID = {0}", objID);
if (nTmp >= 10)
break;
}
System.Threading.Monitor.Exit(m_list);
}
}
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10000; i++)
{
A a;
B b;
C c;
a = new A();
b = new B();
c = new C();
a.m_ID = 3 * i;
b.m_ID = 3 * i+1;
c.m_ID = 3 * i+2;
ObjectMgr.Register(a);
ObjectMgr.Register(b);
ObjectMgr.Register(c);
if (i % 100 == 0)
{
Console.WriteLine("i={0}",i);
}
}//
while (ObjectMgr.GetCnt() > 0)
{
Console.WriteLine("There are {0} objects in list",
ObjectMgr.GetCnt());
ObjectMgr.PrintUnreleasedObjects();
System.Threading.Thread.Sleep(5000);
GC.Collect();
}
}
}
}