Z
Zeng
I finally narrowed down my code to this situation, quite a few (not all) of
my CMyClass objects got hold up after each run of this function via the
simple webpage that shows NumberEd editbox. My memory profile shows that
those instances survive 3 rounds of GC collections - it's not what I
expected. In my real code, CMyClass occupies big amount of memory and they
all share one stance of another class that I don't have enough memory hold
more than a just a few in the memory. Notice that the finalizaer the my
CMyClass makes a big difference in demonstrating this issue, w/o it the
problem doesn't exist. The interesting thing is if I run the page again,
the old dangling ones got destroyed and the new ones become dangling. Am I
missing something about the GC? Do I need to explicitly implement and call
dispose for these classes instead of relying on GC to promptly collect it?
Apparently somehow these objects can survive the automatic
collections...disposing it would help. Thanks for your comment and help.
internal class CMyClass
{
ArrayList m_array = new ArrayList( 50000 );
private string m_idStr;
private Guid m_guid;
internal CMyClass( int n )
{
for( int i = 0; i < n; ++i )
m_array.Add( Guid.NewGuid() );
m_guid = Guid.NewGuid();
m_idStr = m_guid.ToString();
}
internal Guid id
{
get{ return (Guid ) m_array[ 0 ]; }
}
~CMyClass()
{
// Trace.Write( m_guid, m_idStr );
}
}
private void RunBtn_Click(object sender, System.EventArgs e)
{
ResultEd.Text = "";
try
{
for( int i = 0; i < int.Parse( NumberEd.Text ); ++i )
{
Hashtable table = new Hashtable( 100 );
ArrayList ids = new ArrayList( 10 );
for( int j = 0; j < 10; ++j )
{
Guid id = Guid.NewGuid();
table[ id ] = null;
ids.Add( id );
}
for( int k=0; k < 10; ++k )
{
foreach( Guid id in ids )
{
table[ id ] = new CMyClass( 10 );
}
CMyClass myobj;
foreach( Guid id in ids )
{
myobj = (CMyClass) table[ id ];
myobj.id.ToString();
}
} // for k
} // for
}
catch( Exception ex )
{
ResultEd.Text = ex.Message + "...CallSTack:" +
ex.StackTrace;
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
ResultEd.Text = "Done";
}
my CMyClass objects got hold up after each run of this function via the
simple webpage that shows NumberEd editbox. My memory profile shows that
those instances survive 3 rounds of GC collections - it's not what I
expected. In my real code, CMyClass occupies big amount of memory and they
all share one stance of another class that I don't have enough memory hold
more than a just a few in the memory. Notice that the finalizaer the my
CMyClass makes a big difference in demonstrating this issue, w/o it the
problem doesn't exist. The interesting thing is if I run the page again,
the old dangling ones got destroyed and the new ones become dangling. Am I
missing something about the GC? Do I need to explicitly implement and call
dispose for these classes instead of relying on GC to promptly collect it?
Apparently somehow these objects can survive the automatic
collections...disposing it would help. Thanks for your comment and help.
internal class CMyClass
{
ArrayList m_array = new ArrayList( 50000 );
private string m_idStr;
private Guid m_guid;
internal CMyClass( int n )
{
for( int i = 0; i < n; ++i )
m_array.Add( Guid.NewGuid() );
m_guid = Guid.NewGuid();
m_idStr = m_guid.ToString();
}
internal Guid id
{
get{ return (Guid ) m_array[ 0 ]; }
}
~CMyClass()
{
// Trace.Write( m_guid, m_idStr );
}
}
private void RunBtn_Click(object sender, System.EventArgs e)
{
ResultEd.Text = "";
try
{
for( int i = 0; i < int.Parse( NumberEd.Text ); ++i )
{
Hashtable table = new Hashtable( 100 );
ArrayList ids = new ArrayList( 10 );
for( int j = 0; j < 10; ++j )
{
Guid id = Guid.NewGuid();
table[ id ] = null;
ids.Add( id );
}
for( int k=0; k < 10; ++k )
{
foreach( Guid id in ids )
{
table[ id ] = new CMyClass( 10 );
}
CMyClass myobj;
foreach( Guid id in ids )
{
myobj = (CMyClass) table[ id ];
myobj.id.ToString();
}
} // for k
} // for
}
catch( Exception ex )
{
ResultEd.Text = ex.Message + "...CallSTack:" +
ex.StackTrace;
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
ResultEd.Text = "Done";
}