2013-02-25 2 views
1

Я создаю инструмент для загрузки теста (отправляет http: GET), и он отлично работает, но в конечном итоге умирает из-за ошибки из памяти.Out of Memory Threading - Perf Test Tool

ASK: Как сбросить потоки, чтобы этот цикл мог непрерывно выполняться, а не ошибаться?

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.... 
    } 
+0

Здравомыслящий реализация вашей инфраструктуры будет означать, что это не может Нагрузочные испытания правильный компонент. Вы выполняете HTTP GET, который должен быть Pure Function. Это означает, что каждому кэшированию разрешается принимать один и тот же результат каждый раз. Теоретически вы могли бы только сделать запрос SINGLE HTTP с 1000 потоками. – Aron

+0

@Aron: Как я могу предотвратить кеширование? Вот почему я делал звонки на все эти потоки отдельно, чтобы не создавать один GET с этими 1000 потоками. В моем запросе GET я включаю & _ = (т. Е. Http: //...getstuff? Whatstuff = thisstuff & _ = 23424). – JaJ

+0

, который должен это сделать. – Aron

ответ

1

Вы инстанцируете Тема оставила справа и в центре. Вероятно, это проблема. Вы хотите заменить

new Thread(LoadTest).Start(); 

с

Task.Run(LoadTest); 

это будет запускать LoadTest на тему в ThreadPool, вместо того, чтобы использовать ресурсы, чтобы создать новую тему каждый раз. ОДНАКО. Затем это вызовет другую проблему.

Темы ThreadPool - это ограниченный ресурс, и вы хотите как можно скорее вернуть потоки в 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); 
1

Используйте ThreadPool и использовать QueueUserWorkItem вместо создания тысячи потоков. Нити - дорогие объекты, и неудивительно, что у вас не хватает памяти, и вы не сможете получить какую-либо производительность (в вашем тестовом инструменте) с таким количеством потоков.

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.... 
    } 
+0

На самом деле вам не нужно 500 потоков для запуска 200 http-соединений, если вы используете асинхронный код. На самом деле попытка запустить 200 потоков будет убивать вас компьютер, скорее всего. – Aron

+0

Полностью согласен с вами. Я разместил его только для примера конфигурации. Совет, будьте логичны и решайте для себя :). Кроме того, это просто максимальное количество потоков. Пул не создает сразу 500 нитей. – user1873415