N
Nick Farina
After two days of debugging, I have finally discovered a very odd bug when
using the XmlSerializer object and the SqlConnection object. It seems that
if you instantiate an XmlSerializer object before opening a connection to a
SQL database, then all future Thread objects created in the entire program
will not be garbage collected.
Since my application is a TCP server, it is constantly creating threads
using the Thread object. If I let it run for a couple days, and watch the
Handle count in the Task Manager (click View...Select Columns...) or even
better, SysInternal's Process Explorer, the thread handle count will get
well above 200,000. Eventually the app runs out of memory.
I'm using the 1.1 framework. Try this sample code below and see for
yourself (compile as a console app):
class Class1
{
[STAThread]
static void Main(string[] args)
{
// any valid database connect string
string dbConnectString = "replace this with your DB connect string";
SqlConnection db = new SqlConnection(dbConnectString);
Console.WriteLine("Press enter to start...");
Console.ReadLine();
// All you need to do is instantiate the XmlSerializer to produce
the problem.
// If you switch the next two lines, the problem goes away!
XmlSerializer xs = new XmlSerializer(typeof(object));
db.Open(); db.Close();
// create and finish a bunch of thread objects
for (int x=0;x<100;x++)
{
Thread myThread = new Thread(new ThreadStart(DoNothing));
myThread.Start();
myThread.Join();
}
// this should clean up all thread objects (and therefore, handles)
GC.Collect();
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
}
static void DoNothing(){}
}
If you compile and run the above class, then watch its process, it will
allocate approximately 570 system handles and never release them.
Obviously, the workaround is to open up a connection to the database before
using the XmlSerializer. But unfortunately, I'm using the XmlSerializer to
parse an XML app configuration file which contains the DB connect string
itself. Chicken-and-egg you might say.
nick
=====================
Nick Farina
CTO
Spotlight Mobile, Inc.
=====================
using the XmlSerializer object and the SqlConnection object. It seems that
if you instantiate an XmlSerializer object before opening a connection to a
SQL database, then all future Thread objects created in the entire program
will not be garbage collected.
Since my application is a TCP server, it is constantly creating threads
using the Thread object. If I let it run for a couple days, and watch the
Handle count in the Task Manager (click View...Select Columns...) or even
better, SysInternal's Process Explorer, the thread handle count will get
well above 200,000. Eventually the app runs out of memory.
I'm using the 1.1 framework. Try this sample code below and see for
yourself (compile as a console app):
class Class1
{
[STAThread]
static void Main(string[] args)
{
// any valid database connect string
string dbConnectString = "replace this with your DB connect string";
SqlConnection db = new SqlConnection(dbConnectString);
Console.WriteLine("Press enter to start...");
Console.ReadLine();
// All you need to do is instantiate the XmlSerializer to produce
the problem.
// If you switch the next two lines, the problem goes away!
XmlSerializer xs = new XmlSerializer(typeof(object));
db.Open(); db.Close();
// create and finish a bunch of thread objects
for (int x=0;x<100;x++)
{
Thread myThread = new Thread(new ThreadStart(DoNothing));
myThread.Start();
myThread.Join();
}
// this should clean up all thread objects (and therefore, handles)
GC.Collect();
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
}
static void DoNothing(){}
}
If you compile and run the above class, then watch its process, it will
allocate approximately 570 system handles and never release them.
Obviously, the workaround is to open up a connection to the database before
using the XmlSerializer. But unfortunately, I'm using the XmlSerializer to
parse an XML app configuration file which contains the DB connect string
itself. Chicken-and-egg you might say.
nick
=====================
Nick Farina
CTO
Spotlight Mobile, Inc.
=====================