Как избежать нехватки памяти в приложении с высоким потреблением памяти? C / C ++

Создайте UNIQUE CONSTRAINT, на котором вы думаете, что существует дубликат.

как

ALTER TABLE MYTABLE ADD CONSTRAINT constraint1 UNIQUE(column1, column2, column3)
13
задан KPexEA 12 April 2009 в 14:13
поделиться

13 ответов

Во-первых, в 32-разрядной системе вы всегда будете ограничены 4 ГБ памяти, независимо от настроек файла подкачки , (Из них только 2 ГБ будут доступны вашему процессу в Windows. В Linux у вас обычно будет доступно около 3 ГБ)

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

Во-вторых, может помочь выделение меньших порций памяти за раз. Зачастую легче найти 4 блока по 256 МБ свободной памяти, чем один блок по 1 ГБ.

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

16
ответ дан 1 December 2019 в 19:41
поделиться

Вам не нужно переключаться на 64-битные машины, а также вам не нужно большинство из 1000 вещей, предложенных другими. Вам нужен более продуманный алгоритм.

Вот некоторые вещи, которые вы можете сделать, чтобы помочь в этой ситуации:

  • Если вы работаете в Windows, используйте File Maps (пример кода ). Это даст доступ к файлу через один указатель буфера, как будто вы читаете весь файл в памяти, только фактически не делая этого. Последние версии Linux Kernel имеют похожий механизм.
  • Если вы можете, и похоже, что вы могли бы, сканируйте файл последовательно и избегайте создания DOM в памяти. Это значительно уменьшит время загрузки и требования к памяти.
  • Используйте пул памяти! У вас, вероятно, будет много крошечных объектов, таких как узлы, точки и еще много чего. Используйте объединенную память, чтобы выручить (я предполагаю, что вы используете неуправляемый язык. Поиск пулированного выделения и пулов памяти).
  • Если вы используете управляемый язык, по крайней мере переместите эту конкретную часть в неуправляемую. язык и взять под контроль память и чтение файлов. Управляемые языки имеют нетривиальные накладные расходы, как по объему памяти, так и по производительности. (Да, я знаю, что это помечено как "C ++" ...)
  • Попытка разработать алгоритм на месте, в котором вы одновременно считываете и обрабатываете только минимальное количество данных, поэтому ваши требования к памяти будут снижаться.

Наконец, позвольте мне указать, что сложные задачи требуют сложных мер. Если вы думаете, что можете себе позволить 64-разрядную машину с 8 ГБ ОЗУ, просто используйте «чтение файла в память»,

0
ответ дан 1 December 2019 в 19:41
поделиться

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

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

Теперь это звучит просто, не так ли? (Рад, что я не обязан это делать :))

0
ответ дан 1 December 2019 в 19:41
поделиться

Звучит так, как будто вы выполняете txt для бинарного разговора, так зачем вам хранить все данные в памяти? .
Разве вы не можете просто прочитать примитив из txt (xml) и сохранить его в двоичном потоке?

0
ответ дан 1 December 2019 в 19:41
поделиться

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

Если вы не хотите тратить время на оптимизацию использования памяти, почему бы не попробовать Conservative Garbage Collector ? Это замена плагина для malloc () / new и free (). На самом деле, free () не работает, поэтому вы можете просто удалить эти вызовы из вашей программы. Если вместо этого вы вручную оптимизируете свою программу и управляете пулом памяти, как предлагалось ранее, вы в конечном итоге будете выполнять большую часть работы, которую CGC уже выполняет для вас.

1
ответ дан 1 December 2019 в 19:41
поделиться

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

1
ответ дан 1 December 2019 в 19:41
поделиться

На 32-битной XP максимальное адресное пространство программы составляет 2 ГБ. Затем происходит фрагментация из-за загрузки DLL и драйверов в ваше адресное пространство. Наконец, у вас есть проблема фрагментации кучи.

Ваш лучший шаг - просто покончить с этим и запустить как 64-битный процесс (в 64-битной системе). Внезапно все эти проблемы уходят. Вы можете использовать лучшую кучу, чтобы смягчить эффекты фрагментации кучи, и вы можете попробовать использовать VirtualAlloc, чтобы захватить вашу память в один большой непрерывный блок (а затем вы сможете управлять этим оттуда!), Чтобы препятствовать DLL / драйверам фрагментировать ее. [1261 Наконец, вы можете разделить ваш BSP по процессам. Сложно и больно, и, честно говоря, просто записать его на диск будет проще, но теоретически вы могли бы добиться более высокой производительности, если бы группа процессов обменивалась информацией, если бы вы могли сохранять все резидентным (и предполагая, что вы можете быть умнее, чем память, чем ОС может справиться с буферизацией файлов ... что очень важно, если). Каждому процессу потребовалось бы гораздо меньше памяти и, следовательно, он не должен работать до предела адресного пространства 2 ГБ. Конечно, вы будете прожигать RAM / swap намного быстрее.

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

Мальчик, не '

1
ответ дан 1 December 2019 в 19:41
поделиться

Вы должны понимать, что виртуальная память отличается от «ОЗУ» тем, что объем виртуальной памяти вы Вы используете общий объем, который вы зарезервировали, в то время как реальная память (в Windows она называется «Рабочий набор») - это память, которую вы фактически изменили или заблокировали.

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

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

1
ответ дан 1 December 2019 в 19:41
поделиться

Предполагается, что вы используете Windows XP, если у вас только предел памяти и вы не хотите или не имеете времени чтобы переработать код, как предложено выше, вы можете добавить ключ / 3GB в ваш файл boot.ini , а затем просто установить переключатель компоновщика, чтобы получить дополнительный 1 ГБ памяти.

2
ответ дан 1 December 2019 в 19:41
поделиться

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

3
ответ дан 1 December 2019 в 19:41
поделиться

Похоже, вы уже используете SAX подход к обработке XML (загрузка XML на ходу вместо всего сразу).

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

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

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

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

Вы также можете рассмотреть вопрос о введении ограничений на ввод для вашей программы и иметь другой для 32 и 64-битные системы.

4
ответ дан 1 December 2019 в 19:41
поделиться

Проверяли ли вы, чтобы нигде не было утечки памяти?

Поскольку ваша программа переносима на Linux, Я предлагаю запустить его под Valgrind, чтобы убедиться.

4
ответ дан 1 December 2019 в 19:41
поделиться

Как вы распределяете память для очков? Вы распределяете очки по одному (например, pt = новая точка). Затем, в зависимости от размера точки, некоторая память может быть потрачена впустую. Например, в Windows память выделяется в количестве, кратном 16 байтам, поэтому даже если вы попросите попытаться выделить 1 байт, ОС фактически выделит 16 байт.

Если это так, может помочь использование распределителя памяти. Вы можете сделать быструю проверку, используя STL allocator. (перегрузите новый оператор для класса Point и используйте распределитель STL для выделения памяти, а не 'malloc' или новый оператор по умолчанию).

1
ответ дан 1 December 2019 в 19:41
поделиться