2010-04-06 4 views
2

Мы видим очень большое использование памяти в веб-приложениях .NET, которые используют XmlDocument. Небольшой XML-документ (~ 5 МБ) загружается в объект XmlDocument и сохраняется в HttpContext.Cache для упрощения запросов и преобразования XSLT при каждой загрузке страницы. XML периодически изменяется на диске, поэтому кэш имеет зависимость от файла.Использование памяти кэширования XmlDocument

Такое приложение, похоже, использует сотни мегабайт оперативной памяти.

Я экспериментировал с запросом сбора мусора при каждом запуске запроса, и это позволяет использовать ОЗУ намного ниже, но я не могу представить, что это хорошая практика.

Есть ли у кого-нибудь какие-либо предложения относительно того, как мы можем достичь той же цели, но с более низким потреблением ОЗУ?

+0

Я подозреваю, что в вопросе «кажется, используется». Если вы используете фиктивный (как можно ближе к Zero MB, как вы можете получить) XML-документ, соответственно снижается использование вашей памяти? Является ли память hog XML Document или XSLT Transform? –

+0

Использует ли использование памяти продолжать расти, если вы оставите ее в покое или она будет стабилизироваться с течением времени? – AnthonyWJones

+0

Binary Worrier - я говорю «появляется», потому что, используя несколько методов для наблюдения за увеличением использования памяти, я не мог дать вам точную цифру, но она определенно возрастает. Я считаю, что это XML-документ, а не преобразование. AnthonyWJones - Он стабилизируется при простоях между загрузками страниц, и даже с непрерывным трафиком он выравнивается со временем, то есть он не продолжает расти навсегда. –

ответ

5

Мои два цента. , ,

Я был бы обеспокоен тем, что использование памяти было экспоненциальным в зависимости от размера XML-документа. например 1 Мб памяти XML-файла оседает в 10 МБ, 2 МБ сглаживается при 30 МБ и т. Д.

Кроме того, рассмотрите стоимость XML-файла не столько на размер байта, сколько на стоимость каждого узла. Если ваш XML-документ размером 5 МБ скажет два узла данных, то представление документа в памяти не будет намного больше, чем 5 МБ (на самом деле это может быть намного меньше, учитывая, что двоичные данные в XML будут вдвое больше, чем в Память).

* Если ваш XML-документ является utf-8, и у вас есть два больших текстовых узла, тогда представление в памяти может быть 10mb (текст может быть сохранен в .net-строках, которые являются Unicode, и будет в два раза больше ширины стандартного текста английского языка UTF-8).

Если XML-документ состоит из множества дискретных строковых значений, то каждый узел является объектом, каждое имя узла является объектом, каждое значение узла является объектом. Таким образом, предполагая, что ссылки составляют 4 байта, это (по крайней мере) дополнительные 12 байт на узел.

Теперь, если у вас много узлов, и предположим, что ваша средняя длина имени узла + равна 20 символам, тогда служебные служебные данные для 5-мегабайтного файла составляют 3 МБ, а также дополнительные 100% для utf-8 для Unicode-преобразование, требуется 5MB + 5mb + 3mb (не менее) = 13mb (не менее) памяти для хранения XML-файла 5mb. , , и это не считается байтами, потерянными для выравнивания памяти, или дополнительными байтами, используемыми для хранения размера каждого строкового объекта **.

считают также, что, поскольку вы кэшировать документ XML, все эти объекты сразу стали поколения 2 коллекционные предметы, которые в основном означает ГХ будет очень лень ходить, что значительную кучу, чтобы увидеть, что он может собрать.

См. Rico Mariani's When to call GC.Collect() в тех случаях, когда это не только ОК для вызова GC Collect, но когда необходимо его вызвать.

Надеюсь, это поможет, извините, если я проповедую хору по размеру памяти.

* Я понятия не имею, действительно ли это так, но было бы удивлено, если это не так.
** Я предполагаю, что .net-строки хранят размер строки до/после фактических символов строки, это может значительно увеличить представление в памяти и дополнительные 4-8 байтов на узел, давая при 20-байтной стоимости на 20 байтов имени/значения узла. Это эффективно увеличивает накладные расходы, чтобы соответствовать размеру сохраненных данных.

1

Поскольку агрессивные GCing очищают вещи, вы должны искать места, где вы не можете уничтожить объекты, которые реализуют IDisposable. Возможно, вам нужно посмотреть свой код с помощью XSL Transform, чтобы убедиться, что используемые там объекты правильно расположены.

Смежные вопросы