Как решить проблему снижения производительности приложения VB.NET 1.1? - PullRequest
2 голосов
/ 20 мая 2010

У меня есть однопоточное приложение формы Windows, написанное с VB.NET и предназначенное для Framework 1.1 . Программное обеспечение обменивается данными с внешними платами через последовательный интерфейс и состоит в основном из конечного автомата 1006 *, который выполняет некоторые тесты и работает в цикле с таймером и интервалом 50 мс.

Обратная связь с пользовательским интерфейсом осуществляется через некоторые пользовательские события, возникающие во время тестов.

Проблема, которая сводит меня с ума, заключается в том, что производительность немного снижается с течением времени, в частности после 1200/1300 тестовых операций. Занимаемая память не увеличивается со временем, эта проблема проявляет интерес только к процессору.

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

Я знаю, что это сложно, не глядя на код, но у вас есть предложения, как мне решить проблему?

РЕДАКТИРОВАТЬ : Я действительно растерялся, после пары интенсивных работ приложение начинает замедляться. Выбранная строка связана с ее процессом, если это может помочь.

EDIT2 : с помощью диспетчера задач Windows я обнаружил, что счетчик «Ручки» увеличивается на на 1 в конце каждой операции. Я не знаю, является ли это причиной, но приложение начинает замедляться, когда счетчик меток достигает примерно 1500 меток. Я проверил, что все необходимые RemoveHandler вызываются после каждой операции. Есть идеи?

EDIT3 : Я обнаружил, что проблема с дескрипторами генерируется библиотекой C ++ , которую мы используем для связи с последовательным устройством. Это происходит как в .NET 1.1, так и .NET 2.0. Разница, и это странно, заключается в том, что если целевое .NET 1.1 приложение замедляется / замораживается вместо .NET 2.0, я достиг более 30000 дескрипторов без потери производительности. Теперь я не знаю, действительно ли проблема вызвана этими потерянными дескрипторами, я попытаюсь попросить разработчиков библиотеки C ++ исправить ее и посмотреть, решит ли она проблему, возникшую у меня в .NET 1.1.

полное изображение здесь

альтернативный текст http://img341.imageshack.us/img341/6923/process.png

Ответы [ 4 ]

2 голосов
/ 27 мая 2010

ОК, поскольку вы не можете использовать Performance Profiler, я могу подумать о двух вещах, которые стоит попробовать.

1) Это тупой / очевидный вопрос. Вы абсолютно уверены, что утилизируете все, что реализует IDispose?
Даже если вы уверены, что вернитесь и проверьте еще раз, следите за временными объектами, которые не будут выбрасываться, например,

   string s = objA.GetAThing().ToString()

где GetAThing () возвращает объект, который реализует IDispose.

2) Вы пытались форсировать сборку мусора?
Прочитайте Краткие сведения о производительности Рико Мариани , иногда не просто нормально звонить GC.Collect(), иногда это необходимо.
У нас есть большое богатое приложение .Net winforms, для которого нам нужно , чтобы вызвать коллекцию каждые десять минут или около того. Если мы этого не сделаем, приложение начнет работать через пару часов.

Надеюсь, это поможет:)

UPDATE
Это позор. У вас есть источник C ++? Или вы застряли с этой проблемой?

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

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

2 голосов
/ 20 мая 2010

Полное раскрытие: я в команде Visual Studio Profiler.

Редактировать: следующее не полезно, поскольку VS Profiler не работает с .NET 1.1. Вы пытались запустить свой код под профилировщиком? Visual Studio 2005/2008 (Developmen Edition / Team Suite) и Visual Studio 2010 Premium / Ultimate имеют встроенный профилировщик. Также доступны сторонние профилировщики .NET.

Запуск вашего кода под профилировщиком покажет вам, где ваш процессор выполняет большую работу. Если вы профилируете только в то время, когда производительность снижается, результаты должны помочь понять, почему.

Кроме того, вы можете смоделировать дешевое профилирование: отлаживайте свое приложение и периодически заходите в него, чтобы посмотреть, что выполняется в стеке вызовов.


Кроме того, на вашем компьютере установлена ​​ .NET Framework 1.1 SP1 ? Вы можете воспроизвести эту проблему на других машинах?

1 голос
/ 28 мая 2010

Ммм

С такой ограниченной информацией это может быть миллион вещей.

Используя немного программирования 'Zen' , я бы сказал, избавьтесь от таймера и начните использовать Threads.

Используйте обычные шаблоны наличия флага отмены и запускайте тесты в цикле while (если это необходимо).

1 голос
/ 24 мая 2010

Во-первых, я бы использовал профилировщик производительности, включенный в Windows, так как Тесс предлагает здесь .

Тогда я бы использовал windbg так, как она предлагает здесь .

Я только предлагаю windbg second, потому что, если вы не использовали его, вы будете в течение небольшого сеанса WTF, пока не получите его (хотя это совершенно стоит получить). Возможно, играя со счетчиками, вы можете найти проблему.

...