2

我正在创建一个工具来加载测试(发送 http: GETs),它运行良好,但最终由于内存不足错误而死。

问:我怎样才能重置线程,以便这个循环可以持续运行并且不会出错?

    static void Main(string[] args)
    {
       System.Net.ServicePointManager.DefaultConnectionLimit = 200;

       while (true)
        {
            for (int i = 0; i < 1000; i++)
            {
                new Thread(LoadTest).Start(); //<-- EXCEPTION!.eventually errs out of memory
            }
            Thread.Sleep(2);
        }
    }

    static void LoadTest()
    {
        string url = "http://myserv.com/api/dev/getstuff?whatstuff=thisstuff";

        // Sends http get from above url ... and displays the repose in the console....
    }
4

3 回答 3

1

使用ThreadPool并使用 QueueUserWorkItem 而不是创建数千个线程。线程是昂贵的对象,内存不足也就不足为奇了,此外,在有这么多线程的情况下,您将无法获得任何性能(在您的测试工具中)。

于 2013-02-25T20:07:41.373 回答
1

您的代码片段创建了很多线程,难怪它最终会耗尽内存。这里最好使用线程池。您的代码将如下所示:

    static void Main(string[] args)
    {
        System.Net.ServicePointManager.DefaultConnectionLimit = 200;
        ThreadPool.SetMaxThreads(500, 300);
        while (true)
        {
            ThreadPool.QueueUserWorkItem(LoadTest);
        }
    }

    static void LoadTest(object state)
    {
        string url = "http://myserv.com/api/dev/getstuff?whatstuff=thisstuff";
        // Sends http get from above url ... and displays the repose in the console....
    }
于 2013-02-25T20:14:17.887 回答
1

您正在实例化左右和中心的线程。这很可能是你的问题。你想更换

new Thread(LoadTest).Start();

Task.Run(LoadTest);

这将在 ThreadPool 中的线程上运行您的 LoadTest,而不是每次都使用资源来创建一个新线程。然而。这将暴露一个不同的问题。

ThreadPool 上的线程是有限资源,您希望尽快将 Threads 返回到 ThreadPool。我假设您使用的是同步下载方法,而不是 APM 方法。这意味着当请求被发送到服务器时,产生请求的线程正在休眠,而不是去做一些其他的工作。

要么使用(假设.net 4.5)

var client = new WebClient();
var response = await client.DownloadStringTaskAsync(url);
Console.WriteLine(response);

或使用回调(如果不是 .net 4.5)

var client = new WebClient();
client.OnDownloadStringCompleted(x => Console.WriteLine(x));
client.BeginDownloadString(url);
于 2013-02-25T20:21:05.097 回答