У меня есть консольное приложение для Windows, которое должно работать без перезапусков в течение нескольких дней и месяцев.Приложение извлекает «работу» из MSMQ и обрабатывает ее.Существует 30 потоков, которые одновременно обрабатывают рабочий блок.
Каждый рабочий блок, поступающий из MSMQ, составляет приблизительно 200 КБ, большая часть которого размещена в одном объекте String.
Я заметил, что после обработкиОколо 3-4 тысяч этих рабочих блоков потребляют слишком много памяти приложения, потребляя 1 - 1,5 ГБ памяти.
Я запустил приложение через профилировщик и заметил, что большая часть этой памяти (возможно, концерт или около того) не используется в куче больших объектов, но структура фрагментирована.
Я обнаружил, что90% этих неиспользованных (собранных мусором) байтов были ранее выделены String.Я начал подозревать, что строки, поступающие из MSMQ, были выделены, использованы, а затем освобождены и, следовательно, являются причиной фрагментации.
Я понимаю, что такие вещи, как GC.Collect (2 или GC.Max ...) не поможет, поскольку они собирают кучу больших объектов, но не сжимают ее (в этом и заключается проблема).Поэтому я думаю, что мне нужно кешировать эти строки и как-то их использовать повторно, но поскольку строки неизменяемы, мне придется использовать StringBuilders.
Мой вопрос: есть ли способ не изменять базовую структуру (то есть, используя MSMQ, так как это что-то, что я не могу изменить), и все же избегайте инициализации новой строки каждый раз, чтобы избежать фрагментации LOH?
Спасибо, Яннис
ОБНОВЛЕНИЕ: О том, как это "рабочие "чанки" в настоящее время извлекаются
В настоящее время они хранятся в виде объектов WorkChunk в MSMQ.Каждый из этих объектов содержит строку с именем Contents и другую строку с именем Headers.Это фактические текстовые данные.Я могу изменить структуру хранения на что-то другое, если это необходимо, и, возможно, на базовый механизм хранения, если это необходимо, на что-то другое, чем MSMQ.
На стороне рабочих узлов в настоящее время мы делаем
WorkChunk chunk = _Queue.Receive ();
Таким образом, на этом этапе мы мало что можем кэшировать.Если бы мы как-то изменили структуру (структуры), то, я думаю, мы могли бы немного продвинуться.В любом случае, нам придется разобраться с этой проблемой, поэтому мы сделаем все необходимое, чтобы не тратить месяцы работы.
ОБНОВЛЕНИЕ: Я попробовал некоторые из предложенийниже и заметил, что эта проблема не может быть воспроизведена на моем локальном компьютере (под управлением Windows 7 x64 и 64-битное приложение).это намного усложняет ситуацию - если кто-нибудь знает, почему, тогда это действительно поможет переопределить эту проблему локально.