Ограничение использования оперативной памяти.(C # .NET) - PullRequest
2 голосов
/ 20 февраля 2011

Есть огромные файлы размером около 100Мб.Я хочу загрузить их в память (RAM), обработать и сохранить где-нибудь.

В то же время я хочу, чтобы существовал предел использования памяти.Например, 100Mb, чтобы мое приложение не использовало больше, чем этот предел памяти.Если предел превышен, файл обрабатывается частями.

Мое понимание этого:

var line = file.ReadLine();
var allowed = true;

while( allowed && line != null ) 
{
   var newObject = new SomeObject( line );
   list.add( newObject );

   // Checking the memory
   allowed = CheckUsedMemory(); 

   line = file.ReadLine()
} 

Как ограничить использование оперативной памяти?Как реализовать метод CheckUsedMemory?Спасибо.

UPD

Спасибо всем за полезные советы.

Ответы [ 5 ]

5 голосов
/ 20 февраля 2011

Вы можете попробовать:

long usedMemory = GC.GetTotalMemory(true);

или

long usedMemory = GC.GetTotalMemory(false);

Первый вызовет сбор мусора (очистку) памяти, поэтому он медленнее (миллисекунды)

Затем прочитайте это, чтобы увидеть, сколько памяти имеет ваша машина:

Как вы получаете общий объем оперативной памяти, которую имеет компьютер?

Помните, что если выработая как 32-битное приложение, вы не можете использовать всю память, и что другие процессы могут использовать память!

2 голосов
/ 20 февраля 2011

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

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

GC.GetTotalMemory () скажет вам, сколько памяти вы используете.

100 МБ ОЗУ немного сегодня.Считывание в память, обработка и возврат на диск могут быть выполнены довольно быстро.Помните, что вы не сможете избежать копирования с диска в память и обратно на диск.Использование StringBuilder (не String) для его хранения не обязательно приведет к чрезмерным накладным расходам в приложении.Запись 100 МБ за одну операцию, безусловно, быстрее, чем одна строка за раз.

2 голосов
/ 20 февраля 2011

Во-первых, спасибо, что знаете о вашем потреблении памяти Если бы только больше программистов были такими внимательными ...

Во-вторых, я бы не стал беспокоиться: возможно, пользователь хочет, чтобы ваше приложение работало как можно быстрее, и готов сжечь 8000 мегабайт памяти, чтобы получить результаты на 5% быстрее. Позволь им. :)

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

И наконец, шаблон доступа, который вы здесь написали (последовательный, построчный), является очень обычным, и, несомненно, разработчики .NET приложили огромные усилия для получения памяти использование от этого шаблона до минимума. Добавление объектов в ваши внутренние деревья по частям - хорошая идея, но очень немногие приложения могут извлечь из этого пользу. (Сортировка слиянием - это отличное приложение, которое значительно выигрывает от частичной обработки.)

В зависимости от того, что вы делаете со своим законченным списком объектов, вы не сможете улучшить работу со всем списком сразу. ИЛИ, вы могли бы извлечь большую выгоду из разрыва его. (Если Map Reduce хорошо описывает вашу проблему с обработкой данных, то, возможно, вам было бы полезно разбить вещи на части.)

В любом случае, я бы немного опасался использовать «память» в качестве эталона для принятия решения о том, когда следует разделить обработку: я бы предпочел использовать «1000 строк ввода» или «десять уровней вложенности» или « запускал станки в течение пяти минут "или что-то, что основано на вводе, а не вторичном эффекте потребляемой памяти.

1 голос
/ 20 февраля 2011

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

1 голос
/ 20 февраля 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...