PHP 7.2 теперь поддерживает тип возвращаемого объекта
http://php.net/manual/en/migration72.new-features.php
function test(object $obj) : object
// return any type of object ...
Вы упомянули использование NHibernate - Вы закрыли свои сеансы NHibernate в соответствующих точках (таких как конец каждого повторения?)
В противном случае затем размер объектной карты, загруженной в память, будет постепенно увеличиваться со временем, и каждый сброс сессии займет все больше больше процессорного времени.
Вот то, где я запустил бы:
Несколько мыслей о возможностях:
Я предлагаю взломать проблему части.
Во-первых, найдите способ воспроизвести проблему 100% времен и быстро. Понизьте таймер так, чтобы сервисы разжигали более часто (например, в 10 раз более быстрый, чем нормальный). Если проблема возникает в 10 раз более быстрая, то она связана с количеством повторений а не к реальному времени или к реальной работе, сделанной сервисами). И Вы сможете сделать следующие шаги, более быстрые, чем один раз в день.
Во-вторых, закомментируйте весь реальный код работы и позвольте только сервисам, таймерам и механизму синхронизации. Если проблема все еще обнаруживается, чем это будет в той части кода. Если это не делает, то начните добавлять назад код, который Вы прокомментировали, одна часть за один раз. В конечном счете необходимо узнать, какая часть кода вызывает проблему.
Хорошие предложения, но пребывают в уверенности, мы попробовали весь обычный поиск и устранение неисправностей. То, что я надеюсь, - то, что это - проблема.NET, о которой кто-то мог бы знать, что мы можем работать над решением.
Мое чувство состоит в том, что, неважно, насколько причудливый первопричина, обычные шаги поиска и устранения неисправностей являются Вашим лучшим выбором для определения местоположения проблемы.
Так как это - проблема производительности, хорошие измерения неоценимы. Полный процесс использование ЦП слишком широк измерение. Где Ваш сервис проводит свое время? Вы могли использовать профилировщика для измерения, это, или просто зарегистрировать различный раздел запускается, и останавливается. Если Вы не можете сделать даже что, то используйте предложение Andrea Bertani - изолированные разделы путем удаления других.
После того как Вы определили местоположение общей области, затем можно сделать даже измерения с более прекрасными зернами, пока Вы не разбираетесь в источнике использования ЦП. Если не очевидно, как зафиксировать его в той точке, у Вас, по крайней мере, есть боеприпасы для намного более конкретного вопроса.
Если Вы на самом деле уже сделали весь этот обычный поиск и устранение неисправностей, впустите нас на секрете.
Походит на проблему поточной обработки с таймером. У Вас могла бы быть одна единица работы, блокирующая другую работу различных рабочих потоков, заставляя их сложить каждый раз огни таймера. Или у Вас могли бы быть проживание экземпляров и работа дольше, чем Вы ожидаете.
Я предложил бы осуществить рефакторинг таймер. Замените его единственным потоком, который стоит в очереди работа над ThreadPool. Можно Спать () поток для управления, как часто он ищет новую работу. Удостоверьтесь, что это - единственное место, где Ваш код является многопоточным. Все другие объекты нужно инстанцировать, поскольку работа подготавливается для обработки и уничтожается после того, как та работа завершается. СОСТОЯНИЕ ЯВЛЯЕТСЯ ВРАГОМ в многопоточном коде.
Другая область, где дизайну недостает, кажется, что у Вас есть многочисленные услуги, которые опрашивают ресурсы, чтобы сделать что-то. Я предложил бы объединить их под единственным сервисом. Они могли бы сделать отдельные вещи, но они работают в унисон; Вы просто используете файловую систему, базу данных, и т.д. как замена на вызовы метода. Кроме того, 2003? Я плохо себя чувствую для Вас.
'Fraid, этот ответ только собирается предложить, чтобы некоторые направления для Вас заглянули, но видевший подобные проблемы в.NET Windows Services у меня есть несколько мыслей, которые Вы могли бы найти полезным.
Мое первое предложение является Вашими сервисами, мог бы иметь некоторые ошибки или в способе, которым они обрабатывают память, или возможно в способе, которым они обрабатывают неуправляемую память. В прошлый раз, когда я разыскал подобную проблему, это оказалось сторонней библиотекой OSS, мы использовали сохраненные дескрипторы для неуправляемых объектов в статическом ЗУ. Чем дольше услуга работала, тем больше дескрипторов сервис взял, которые заставили производительность ЦП процесса резко снижаться очень быстро. Способ попытаться разрешить этот вид проблемы для обеспечения сервисов ничего не хранит в промежутке памяти вызовы таймера, хотя, если сторонние библиотеки используют статическое ЗУ, Вы могли бы иметь, чтобы сделать, что-то умное как создает домен приложения для вызова таймера и угробило домен приложения (и его статическое ЗУ), после того как обработка завершена.
Другая проблема, которую я видел при подобных обстоятельствах, была с кодом синхронизации таймера, являющимся подозреваемым, который в действительности позволил больше чем одному потоку выполнять код обработки сразу. Когда мы отладили код, мы нашли, что 1-й поток блокировал 2-е, и к тому времени, когда 2-е началось было 3-е быть заблокированным. Со временем блокирование длилось дольше и дольше и использование ЦП поэтому направлялось в вершину. Решение мы раньше устраняли проблему, состояло в том, чтобы реализовать надлежащий код синхронизации, таким образом, таймер только начал другой поток, если это не будет заблокировано.
Надежда, которой это помогает, но извинения впереди, если обе моих мысли являются отвлекающими маневрами.
Очевидно довольно трудно удаленно отладить, Вы - неизвестное приложение..., но здесь являетесь некоторыми вещами, на которые я посмотрел бы:
Всего наилучшего