Предотвращение нехватки многопоточных приложений - PullRequest
0 голосов
/ 28 мая 2009

Я написал небольшую собственную программу на C #, которая пакетно конвертирует файлы разных форматов, в основном полагаясь на другие API. В настоящее время пользовательский интерфейс порождает BackgroundWorker (не Thread) для обработки преобразований, а затем заполняет очередь запросами, которые очищаются по мере того, как работник выполняет задания. Сами объекты очереди очень малы (3 строки, чтобы сообщить работнику, что делать) и не сильно влияют на объем памяти программы. Я был довольно сумасшедшим с моим управлением памятью (избавляясь от изображений, когда закончил с ними, и вручную собирая мусор в определенных точках.) Тем не менее, программа имеет тенденцию использовать около 100 МБ памяти за раз, и использует около 50% общее время процессора. Похоже, что если бы я наивно реализовал многопоточность, она бы быстро исчерпала системную память (если CLR не совершит какое-то волшебство, о котором я не знаю).

Существует ли простой / эффективный способ порождения потоков, чтобы не допустить исчерпания памяти системой, кроме перехвата исключений OutOfMemory и отката умершего потока (кажется очень неэффективным, но нет способа сохранить состояние без использования запредельных объемов память)

Ответы [ 4 ]

2 голосов
/ 28 мая 2009

Если вы используете ThreadPool.QueueUserWorkItem для запуска преобразований, вы автоматически получите ограничение на количество запущенных потоков. ThreadPool управляет этим внутри и обрабатывает вызовы в очереди, как только поток пула становится доступным.

0 голосов
/ 28 мая 2009

Исключения из-за недостатка памяти могут быть хитрыми и могут быть вызваны фрагментированной памятью, которая фактически не исчерпывается. Поэтому их может быть сложно выследить.

Тесс из службы поддержки продуктов Microsoft в Швеции (http://blogs.msdn.com/tess/) получил большое количество сообщений об отслеживании памяти, где память поможет в этом процессе.

Хороший профиль вашего приложения также может помочь. У JetBrains есть хороший, как у AQTime.

0 голосов
/ 28 мая 2009

Использование 100 МБ памяти не так уж много для приложения обработки изображений.

Кроме того, в .net, когда вы получаете исключение OutOfMemory, весь процесс умирает, вы не можете восстановиться после этого.

Если вам нужно больше памяти (или, вернее, больше адресного пространства), чем может предоставить система, вы можете либо загружать и извлекать память страницы, либо использовать ее в 64-битном режиме.

Вы можете ограничить размер очереди, чтобы убедиться, что единственным «тяжелым» пользователем памяти является рабочий поток, у вас может быть более одного рабочего потока, что увеличит использование вашей памяти, но и быстрее опустошит очередь, просто помните, что в таких интенсивных процессорных процессах использование большего количества потоков, чем процессорных ядер, неэффективно.

Вы говорите о "наивно реализованной многопоточности", многопоточность полна ловушек - наивная реализация будет неэффективной и полна ошибок.

0 голосов
/ 28 мая 2009

Установите ограничение на размер очереди и заставьте отправителя ждать, если он заполнится Вы должны были бы найти правильный предел размера очереди опытным путем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...