ОС : Windows 7 Embedded
ОЗУ : 1 ГБ
Размер файла подкачки : 500 МБ
Оставшееся дисковое пространство : ~ 1 ГБ
.NET : 2.0
Я работаю над приложением .NET 2.0 Winforms, написаннымв C #, который работает в Windows 7 Embedded, где в системе всего 1 ГБ ОЗУ и довольно ограниченное свободное дисковое пространство (~ 1 ГБ).Мы переходим на Windows 7 Embedded с Windows XP Embedded, и хотя наша программа хорошо работает на Windows XP, она несколько раз выходила из строя из-за нехватки памяти в Windows 7. После сбоев мы добавили файл подкачки объемом 500 МБ (По умолчанию в Windows 7 Embedded размер файла подкачки равен 0 МБ).Однако, поскольку мы сузили исключение нехватки памяти, вызванное увеличением объема выделенной памяти программы, возможно, что предел системного принятия будет достигнут в течение достаточно длительного периода времени, даже с файлом подкачки.Мы не можем быстро перенести наше оборудование на что-то более подходящее и должны найти программное решение, которое может решить эту проблему до следующего выпуска.
Используя инструмент SysInternals VMMap, мы видим, что количество стеков потоков в виртуальной памяти программы медленно увеличивается с течением времени, что в конечном итоге приводит к сбою, когда зафиксированная память программы приводит к превышению системным пределом.Причина увеличения стека потоков была изолирована в .NET 2.0 ThreadPool, который по какой-то причине создает чистое положительное число потоков с течением времени.Мы думаем, что это происходит из-за чрезмерного использования класса System.Timers.Timer в нашем коде, когда каждый экземпляр запускает свой обработчик прошедшего таймера события в ThreadPool, хотя до сих пор неясно, почему ThreadPool хранит так много потоков, даже когдапредполагается, что они не всегда используются обратными вызовами таймера.Некоторые из этих обработчиков событий обрабатывают информацию дольше, чем было бы идеально для потока ThreadPool, при этом худшие нарушители даже вызывают Thread.Sleep ().
Мы придумали несколько возможных решений этой проблемы, включая ограничение количества рабочих потоков ThreadPool, замену более длительных обратных вызовов таймера для потоков и переход на более высокую версию .NET.Последнее решение предполагает, что оптимизация диспетчера ThreadPool была выполнена в течение итераций .NET, что может помочь облегчить проблему.Есть ли какие-то другие очевидные (или неочевидные) решения, которые мы пропустили?
Редактировать: При дальнейшей проверке потоки ThreadPool, которые генерируются и останавливаются, имеют следующий стек вызовов:
ntdll!KiFastSystemCallRet
ntdll!ZwWaitForSingleObject+c
KERNELBASE!WaitForSingleObjectEx+98
kernel32!WaitForSingleObjectExImplementation+75
mscorwks!PEImage::LoadImage+1af
mscorwks!CLREvent::WaitEx+117
mscorwks!CLREvent::Wait+17
mscorwks!ThreadpoolMgr::SafeWait+73
mscorwks!ThreadpoolMgr::WorkerThreadStart+11c
mscorwks!Thread::intermediateThreadProc+49
kernel32!BaseThreadInitThunk+e
ntdll!__RtlUserThreadStart+70
ntdll!_RtlUserThreadStart+1b