Как оценить потребность в памяти по XPathDocument для конкретного файла XML

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

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

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

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

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

3 ответа

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

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

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

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

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

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

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

Да, конечно, вы можете сделать это с классом FileInfo.

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

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

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

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

Другие вопросы по тегам