2010-12-30 3 views
0

Есть ли способ оценить потребность в памяти для создания экземпляра XpathDocument на основе размера файла xml?Как оценить потребность в памяти XPathDocument для конкретного файла xml

XpathDocument xdoc = новый XpathDocument (xmlfile);

Есть ли способ программно остановить процесс создания XpathDocument, если память опустится до очень низкого уровня?

Поскольку он загружает весь xml в память, было бы неплохо узнать заранее, если xml слишком большой. Я обнаружил, что когда я создаю новый XpathDocument с большим xml-файлом, исключение outofmemory никогда не запускается, но процесс замедляется при обходе, только 5 Мб памяти остается доступным, а отчеты диспетчера задач - это не отвечать на запросы. Это произошло с файлом размером 266 МБ, когда было 584 МБ RAM. Я смог загрузить 150-мегабайтный файл без проблем в 18.

После загрузки xml я хочу выполнить запросы xpath с помощью XpathNavigator и XpathNodeIterator. Я использую .net 2.0, xp sp3.

ответ

0

Вы можете просто проверить размер файла и вернуться, если он превышает определенную верхнюю границу.

var xmlFileInfo = new FileInfo(xmlfile); 
var isTooBig = xmlFileInfo.Length > maximumSize 

Это не будет надежным, потому что вы не можете догадаться, каков будет правильный максимальный размер.

+0

Мой вопрос обернулся в основном тем, что размер файла maxium должен быть для объема доступной памяти. Я надеялся сделать лучше, чем просто догадываться. –

+0

@ bill: это нелегко, если возможно, чтобы найти это волшебное значение. Вы читали фантастическую статью Эрика Липперта (статья об ошибках из памяти) (http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer -в-физико-memory.aspx)? Это показывает, насколько сложным может быть этот вопрос. Это в сочетании с тем, что вы не имеете никакого контроля над внутренностями XPathDocument, оставляет вас догадываться ... –

+0

Я подозревал, что это непросто. что я могу сделать, это построить таблицу памяти, используемую XPathDocument для файлов с увеличенными размерами и пойти с этим. –

0

Да, вы можете сделать это с помощью класса FileInfo.

System.IO.FileInfo foo = new System.IO.FileInfo("<your file path as string>"); 
long Size = foo.Length; 
2

Короче говоря, вы не можете, за исключением случаев, когда у вас всегда есть похожие файлы для сбора статистических данных, прежде чем начинать оценки.

Поскольку теги, атрибуты, префикс и пространства пространств имен интернированы, это в значительной степени зависит от структуры XML-файла, насколько эффективным может быть хранилище, а соотношение по сравнению с файлом на диске также зависит от используемой кодировки.

В общем, .NET хранит в памяти любую строку в виде UTF16. Поэтому, даже если не было значительных структурных издержек (представьте XML-файл с единственным корневым тегом и большим количеством обычного текста в нем), используемая память по-прежнему будет удвоена для исходного файла UTF8 (или ASCII или любого другого 8- битное кодирование). Поэтому строковое кодирование является первой частью уравнения.

Другое дело, что структура данных встроена в память, чтобы обеспечить эффективный обход документа. Как правило, узлы строятся и связаны вместе со ссылками. Поэтому каждый узел использует определенный объем памяти; поскольку большинство данных, не относящихся к ценности, являются ссылками, используемая здесь память также сильно зависит от архитектуры (64-разрядная использует вдвое больше памяти для одной ссылки, чем 32-разрядная система). Поэтому, если у вас очень сложный документ с небольшими данными (например, целая куча нескольких разных тегов с небольшим количеством текстовых или атрибутных значений), использование вашей памяти будет намного выше, чем размер оригинального документа, и при этом это также будет сильно зависеть от архитектура вашего приложения работает.

Если у вас есть файл с очень длинными именами тегов и атрибутов и, возможно, тяжелое использование пространства имен по умолчанию, используемая память также может быть намного меньше, чем файл на диске.

Таким образом, при условии произвольного XML-файла с неизвестной кодировкой, разумного объема данных и сложности будет очень сложно получить надежную оценку. Однако, если ваши XML-файлы всегда одинаковы в упомянутых точках, вы можете создать некоторую статистику, чтобы получить коэффициент, который получает соотношение, подходящее для вашей конкретной платформы.

Однако обратите внимание, что просмотр «свободной памяти» в диспетчере задач или разговор о «очень низком уровне памяти» - это очень неопределенные количественные показатели. Виртуальная память, кеши, фоновые приложения и службы и т. Д. Будут влиять на эффективную доступность сырой памяти. Поэтому .NET Framework не может надежно угадать, сколько памяти она должна позволять использовать, чтобы оставаться работоспособной для одного процесса или даже до безопасного исключения OutOfMemoryException. Поэтому, если вы получаете одно из этих исключений, вы обычно находитесь за пределами возможной точки восстановления для своего приложения, и вам не следует пытаться поймать и обработать эти исключения.