Как оптимизировать подкачку страниц для большого в базе данных памяти

У меня есть приложение, где вся база данных реализована в памяти с помощью stl-карты для каждой таблицы в базе данных.

Каждый объект в stl-карте является сложным объектом со ссылками на другие объекты в других stl-картах.

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

Когда приложение работало в течение приблизительно одного часа, затем Windows 2003 SP2 начинает разбивать на страницы части RAM для приложения (Eventhough существует 16 Гбайт RAM на машине).

После приложения были частично разбиты на страницы затем, клиентский вход в систему занимает много времени (10 минут), потому что это теперь генерирует отсутствие страницы для каждого поиска указателя в stl-карте. Если выполнение клиента входит в систему во второй раз прямо после затем, это быстро (немного secs), потому что вся память теперь вернулась в RAM.

Я вижу, что возможно сказать Windows блокировать память в RAM, но это обычно только рекомендуется для драйверов устройств, и только для "маленьких" объемов памяти.

Я предполагаю, что бедные укомплектовывают решение, мог быть должен циклично выполниться через всю базу данных памяти и таким образом сказать Windows, что мы все еще интересуемся хранением модели данных в RAM.

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

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

Есть ли другие более изящные решения?

7
задан Rolf Kristensen 7 June 2010 в 16:39
поделиться

6 ответов

---- Править

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

Могу ли я сказать Windows не выгружать память определенных процессов?

и функция VirtualLock должна выполнять свою работу:

http://msdn.microsoft.com/en- us / library / aa366895 (VS.85) .aspx

---- Предыдущий ответ

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

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

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

Если это проблема с памятью, вам все равно придется переключиться на SQL, и это похоже на хороший момент.

0
ответ дан 7 December 2019 в 07:40
поделиться

Как сказал @Jerry Coffin, похоже, что ваша реальная проблема - утечка памяти. Исправьте это.

Но для протокола, ни одно из ваших "решений для бедных людей" не будет работать. Вообще.

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

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

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

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

Если вы не можете этого сделать, то либо

  • добавьте больше оперативной памяти для решения проблемы (приложение использует 16 ГБ? Тогда добавьте 32 или 64 ГБ), либо
  • перейдите на формат, оптимизированный для эффективного доступа к диску (возможно, база данных SQL)
2
ответ дан 7 December 2019 в 07:40
поделиться

У нас есть похожая проблема, и мы выбрали решение: разместить все в блоке разделяемой памяти. AFAIK, Windows не выводит это на страницу. Однако использование stl-map здесь тоже не для слабонервных и выходит за рамки того, что нам требовалось.

Мы используем Boost Shared Memory , чтобы реализовать это для нас, и это хорошо работает. Внимательно следуйте примерам, и вы быстро приступите к работе. Boost также имеет Boost.MultiIndex , который сделает многое из того, что вы хотите.

В поисках бесплатного решения sql вы смотрели Sqlite ? У них есть возможность работать как база данных в памяти.

Удачи, звучит как интересное приложение.

0
ответ дан 7 December 2019 в 07:40
поделиться

Я могу полагать, что это вина некорректного поведения файла подкачки. Я запускал свои ноутбуки в основном с отключенным файлом подкачки, начиная с nt4.0. По моему опыту, по крайней мере, до XP Pro, Windows навязчиво меняет страницы, просто чтобы обеспечить сомнительное преимущество наличия действительно-очень медленного расширения до максимального рабочего пространства.

Спросите, какие преимущества дает переход на жесткий диск с 16 гигабитами реальной оперативной памяти? Если ваша рабочая установка настолько велика, что для ее выполнения требуется больше виртуальной памяти, чем +10 гигабайт, то, как только свопинг станет действительно необходимым, для завершения требуемых процессов потребуется от немного больше времени до тысяч раз дольше. В Windows неуправляемый кеш файловой системы, кажется, противоречит отношениям.

Теперь, когда у меня (очень) время от времени заканчивается рабочий набор на моих ноутбуках XP, пробок на дорогах нет, виноватое приложение просто вылетает. Утилита для приостановки процессов забивания памяти до этого времени и создания предупреждений была бы неплохой, но таких вещей не бывает, просто нарушения, сбоя, а иногда и explorer.exe тоже выходит из строя.

Файлы подкачки - кому они нужны

0
ответ дан 7 December 2019 в 07:40
поделиться

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

Edit: В Windows есть рабочий триммер набора, который активно пытается удалить неиспользуемые данные. Основная идея заключается в том, что он проходит и помечает страницы как доступные, но оставляет в них данные (а менеджер виртуальной памяти знает, какие данные в них находятся). Если, однако, вы попытаетесь получить доступ к этой памяти до того, как она будет выделена для других целей, она снова будет помечена как используемая, что обычно препятствует ее страничному выводу.

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

5
ответ дан 7 December 2019 в 07:40
поделиться

У меня есть приложение, в котором весь база данных реализована в памяти используя stl-карту для каждой таблицы в база данных.

Это начало конца: std :: map в STL крайне неэффективна с памятью. То же самое относится к std :: list.Каждый элемент будет выделен отдельно, что приведет к довольно серьезной трате памяти. Я часто использую std :: vector + sort () + find () вместо std :: map в приложениях, где это возможно (больше поисков, чем модификаций), и я заранее знаю, что использование памяти может стать проблемой.

Когда приложение было запущено в течение часа или около того, затем Windows 2003 SP2 начинает выгружать части RAM для приложения (хотя на машине 16 ГБ ОЗУ).

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

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

0
ответ дан 7 December 2019 в 07:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: