У меня есть программа на C #, которая работает на виртуальной машине Ubuntu в качестве сервера с использованием mono 5.10. Время от времени, программа начинает использовать много памяти, пока это в конечном счете не падает. Такая утечка памяти может занять несколько дней, и я не смог воспроизвести проблему локально.
В течение последних нескольких дней я использовал монохромный профилировщик, чтобы иметь возможность собирать кучи по требованию. Это дало мне 15Gb + файл. Мне удалось получить снимок кучи с момента утечки памяти, который отображается в профилировщике Xamarin следующим образом:
Запуск mprof-report
дает аналогичный бесполезный отчет.
Ни один из них не поможет устранить проблему. Очевидно, что что-то происходит с пулом потоков, но кажется, что нет способа выяснить, что.
Может помочь возможность увидеть, где расположены объекты, но для этого необходимо включить alloc
в профилировщике, что невозможно из-за размера файла, который он будет создавать.
Что вызывает огромное количество IThreadPoolWorkItem
с? Приложение использует процессор на 30-40%, поэтому кажется, что задачи планируются не так быстро, как процессор.
Есть ли способ перечислить объекты, на которые ссылаются задания ThreadPool? Это, по крайней мере, позволило бы мне определить, какой фрагмент кода выполняется так часто. mprof-report
показывает только обратные ссылки, насколько я вижу, что не очень полезно, поскольку IThreadPoolWorkItem
явно принадлежат самому ThreadPool
.
Обновление: Задачи не связаны (с диском) IO. Во время утечки чтение выполняется с частотой 10 кбит / с, что не должно насыщать диск.
Если подумать: если было запланировано много заданий, разве я не должен видеть множество отдельных IThreadPoolWorkItem
объектов? Поскольку IThreadPoolWorkItem
не является структурой, для реального объекта должна быть отдельная запись, а IThreadPoolWorkItem[]
будет просто массивом указателей. Таким образом, можно предположить, что эти IThreadPoolWorkItem[]
являются просто массивами (в основном) null
указателей.
Обновление: ThreadPool.GetAvailableThreads
показывает, что 2 рабочих потока и 0 потоков порта завершения активны, что, по-видимому, указывает на то, что ThreadPool
работает нормально. Настраиваемое ведение журнала также означает, что я не планирую слишком много задач, и запланированные задачи быстро завершаются.