40 миллионов ошибок страниц.Как это исправить?

StackOverflow https://stackoverflow.com/questions/3941735

  •  30-09-2019
  •  | 
  •  

Вопрос

У меня есть приложение, которое загружает 170 файлов (допустим, это текстовые файлы) с диска в виде отдельных объектов и постоянно хранит их в памяти.Память выделяется один раз, когда я загружаю эти файлы с диска.Таким образом, никакой фрагментации памяти не происходит.Я также использую FastMM, чтобы мои приложения никогда не теряли память.

Приложение сравнивает все эти файлы между собой, чтобы найти сходство.Упрощая, мы можем сказать, что мы сравниваем текстовые строки, но алгоритм намного сложнее, поскольку мне приходится допускать некоторые различия между строками.Каждый файл имеет размер около 300 КБ.Загруженный в память (объект, который его хранит) занимает около 0,4 МБ ОЗУ.Итак, работающее приложение занимает около 60МБ или ОЗУ (рабочий набор).Он обрабатывает данные около 15 минут.Дело в том, что он генерирует более 40 миллионов ошибок страниц.

Почему?У меня около 2 ГБ свободной оперативной памяти.Насколько я знаю, ошибки страниц работают медленно.Насколько они тормозят мою программу?Как я могу оптимизировать программу, чтобы уменьшить количество ошибок на страницах?Я думаю, это как-то связано с локальностью данных.Кто-нибудь знает примеры алгоритмов для этого (Delphi)?

Обновлять:
Но, глядя на количество ошибок страниц (ни одно другое приложение в диспетчере задач не приближается к моему, даже ненамного), я предполагаю, что я мог бы увеличить скорость своего приложения, ЕСЛИ мне удастся оптимизировать структуру памяти (уменьшить количество ошибок страниц).


Delphi 7, Win 7 32 бит, ОЗУ 4 ГБ (3 ГБ видимых, 2 ГБ свободно).

Это было полезно?

Решение

Предостережение: я рассматриваю только проблему сбоя страницы.

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

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

Обратите внимание, что файлы с отображением в памяти — это то, как Windows загружает, среди прочего, .dll и .exe.Я использовал их для сканирования гигабайтных файлов, не нарушая ограничений памяти (в те дни у нас были МБ, а не ГБ оперативной памяти).

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

Другие советы

На моей машине большинство ошибок страниц сообщается для студии разработчика, в которой, как сообщается, возникает 4 миллиона ошибок страниц после общего времени процессора более 30 минут.Вы получите в 10 раз больше и в два раза быстрее.И памяти в моей системе мало.Так что 40 миллионов ошибок кажутся очень большими.

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

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

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

Используете ли вы экспоненциальную систему изменения размера?

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

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

Также избегайте методов Tstringlist.load* для очень больших файлов, IIRC они занимают вдвое больше необходимого места.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top