Sizzle
Sizzle

Reputation: 47

C# ThreadPool - OutOfMemoryException

I am messing around with ThreadPools for the first time for a project and need to be able to queue work items in two different sections of the main method. I made this simple example to test and I keep getting an OutOfMemoryException inside either for loop on the object creation line. Is there a sort of cleanup I need to perform at the end of the execution of a thread in order to free up any memory taken by that thread? If not how do I solve my memory issue?

class Program
{
    public static HashSet<String> domains;
    static void Main(string[] args)
    {
        //Static DB Connection
        //Database Set
        domains = new HashSet<string>();
        while (true)
        {
            //Pull Data From The Database
            String[] chars = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" };
            for (int i = 0; i < 10; i++)
            {
                Loader l = new Loader(chars[i]);
                if (!domains.Contains(chars[i]))
                {
                    lock (domains)
                    {
                        domains.Add(chars[i]);
                    }
                    ThreadPool.QueueUserWorkItem(new WaitCallback(l.ThreadPoolCallback), i);
                }

            }
           for (int i = 0; i < 10; i++)
            {
                Parser p = new Parser();
                ThreadPool.QueueUserWorkItem(new WaitCallback(p.ThreadPoolCallback), i);
            }
        }
    }
}

Parser Class:

 class Parser
{
    public void ThreadPoolCallback(Object threadContext)
    {
        ManualResetEvent eventx = new ManualResetEvent(false);
        //int threadIndex = (int)threadContext;
        Console.WriteLine("Parser Thread: " + threadContext);
        eventx.Set();
    }
}

Loader Class:

class Loader
{
    String ch { set; get; }
    public Loader(String new_ch)
    {
        ch = new_ch;
    }
    public void ThreadPoolCallback(Object threadContext)
    {
        ManualResetEvent eventx = new ManualResetEvent(false);
        Console.WriteLine("Added " + this.ch + " to " + Thread.CurrentThread.GetHashCode());
        //int threadIndex = (int) threadContext;
        //Console.WriteLine("Loader Thread: " + threadContext + " " + ch + "  " + Thread.CurrentThread.GetHashCode());
        lock(Program.domains)
        {
            Program.domains.Remove(this.ch);
            Console.WriteLine("Removed " + this.ch + " from " + Thread.CurrentThread.GetHashCode());
        }
        eventx.Set();
    }

}

Thanks a bunch.

EDIT Thanks for all of the help. I now see the errors I was making

Upvotes: 1

Views: 2383

Answers (3)

roken
roken

Reputation: 3994

You have an infinite while loop that does nothing but spit out new threads. Threads take a significant amount of memory (1MB in 32bit; 4MB in 64bit), so eventually you're going to blow out your memory if you don't exhaust your thread limit first.

Also -- your usage of the ManualResetEvent is incorrect. It needs to be created outside the scope of the method, otherwise it accomplishes nothing (because each thread that enters the method will create a new instance of the resetevent object; in order to synchronize, threads must be accessing the same object).

Upvotes: 2

Les
Les

Reputation: 10605

Though the threadpool limits the number of threads, your loop does not limit the number of user work items on the queue. Your infinite loop will exhaust mem.

Upvotes: 2

code4life
code4life

Reputation: 15794

Like roken said, everything between the lines

while(true)
{
   ....
}

are getting repeated infinitely.

Upvotes: 1

Related Questions