Работа с большими объемами данных в С++

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

Что такое хороший способ справиться с этой ситуацией? Я получаю "плохой дистрибутив", выброшенный из новых и проверенных ловушек, но я все еще сталкиваюсь с крахом. Мне кажется, что я нахожусь в грязных водах, загружая это много данных, но это требование этого приложения для обработки такого рода большой нагрузки данных.

Изменить: сейчас я тестирую 32-битную систему Windows, но приложение будет работать на различных вариантах Windows, Sun и Linux, в основном 64-битных, но 32.

Обработка ошибок не является сильной: она просто обертывает основной код создания с помощью блока catch try, причем catch ищет любое исключение за другую одноранговую жалобу о невозможности ловушки bad_alloc каждый раз.

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

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

Ответ 1

Существует библиотека STXXL, которая предлагает STL-контейнеры для больших наборов данных.

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


Трудно сказать что-либо о сбое вашего приложения, потому что в условиях жесткой памяти существует множество проблем, связанных с жесткой памятью: вы можете набрать ограничение жесткого адресного пространства (например, по умолчанию 32-разрядная версия Windows имеет только адресное пространство 2 ГБ для каждого пользовательского процесса это можно изменить, http://www.fmepedia.com/index.php/Category:Windows_3GB_Switch_FAQ), или быть съеденным живым убийцей OOM (Не мифическое зверь: см. http://lwn.net/Articles/104179/).

В любом случае я бы предложил подумать о способе хранения данных на диске и обработать основную память как своего рода кеш уровня 4 для данных. Например, если у вас есть, скажем, капли данных, затем оберните их в класс, который может прозрачно загружать капли с диска, когда они понадобятся, и регистрируется на каком-то диспетчере памяти, который может попросить некоторых из держателей blob высвободить их память перед условиями памяти становится невыносимой. Таким образом буферный кеш.

Ответ 2

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

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

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

Если пользователь выбирает больше данных, чем может обрабатывать ОС, приложение сильно падает.

В зависимости от ОС это либо: в приложении отсутствует некоторая обработка ошибок выделения памяти, либо вы действительно достигаете предела доступной виртуальной памяти.

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

В моей тестовой системе это число составляет около 2 гигабайт физической памяти.

Звучит так:

  • ваше приложение 32-битное и
  • Ваша ОС использует разделение виртуальной памяти 2 ГБ /2 ГБ.

Чтобы избежать ограничения, вам необходимо:

  • обновите приложение и ОС до 64-разрядных или
  • сообщите OS (патч IIRC для Windows, у большинства Linuxes уже есть), чтобы использовать разделение виртуальной памяти 3 ГБ /1 ГБ. Некоторые 32-разрядные ОС используют разделение памяти 2 ГБ /2 ГБ: 2 ГБ виртуальной памяти для ядра и 2 для пользовательского приложения. Разделение 3/1 означает 1 ГБ виртуальной машины для ядра, 3 для пользовательского приложения.

Ответ 3

Как сохранить таблицу заголовков вместо загрузки всех данных. Загружайте фактическую страницу, когда пользователь запрашивает данные. Также используйте некоторые алгоритмы сжатия данных (например, 7zip, znet и т.д.), Которые уменьшают размер файла. (В моем проекте они уменьшили размер от 200 МБ до 2 МБ).

Ответ 4

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

Чтение больших файлов

Данные переменной длины в файле - пейджинг

Новая ссылка ниже с очень хорошим ответом.

Обработка файлов размером более 2 ГБ

Поисковый запрос: "файл paging lang: С++" добавляет большой или более 2 ГБ для большего количества. НТН

Ответ 5

Не уверен, что вы ударяете его или нет, но если вы используете Linux, malloc обычно не прерывается, а operator new обычно не бросает bad_alloc. Это связано с тем, что Linux превзойдёт и вместо этого убьет ваш процесс, когда он решит, что в системе недостаточно памяти, возможно, при ошибке страницы.

Смотрите: Поиск Google для "oom killer" .

Вы можете отключить это поведение с помощью:

echo 2 > /proc/sys/vm/overcommit_memory

Ответ 6

Перейдите на 64-разрядный процессор, 64-разрядную ОС и 64-разрядный компилятор и убедитесь, что у вас много ОЗУ.

32-разрядное приложение ограничено 2 ГБ памяти (независимо от того, сколько у вас физической памяти). Это связано с тем, что 32-разрядный указатель может адресовать 2 ^ 32 байта == 4 ГБ виртуальной памяти. 20 лет назад это казалось огромным объемом памяти, поэтому оригинальные разработчики ОС выделяли 2 ГБ работающему приложению и зарезервировали 2 ГБ для использования ОС. Существуют различные трюки, которые вы можете сделать для доступа к более чем 2 ГБ, но они сложны. Вероятно, проще перейти на 64-разрядную версию.