Дамп буферизованных данных, когда предел памяти близок - PullRequest
1 голос
/ 09 марта 2011

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

Сложным фактором здесь является то, что мое приложение работает на Linux, OSX и Windows.Но я возьму хороший способ сделать это только на одной платформе и ни за что.

Ответы [ 5 ]

1 голос
/ 18 сентября 2015

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

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

И с умозрительным кэшированием / предварительной выборкой функция значения LRU является странной: вы (будем надеяться) сначала выберете наиболее вероятные для вызова данные, а менее вероятные - позже, поэтому данные LRU в вашей предварительной выборке Кэш может быть менее ценным, чем старые данные. Это может привести к неправильному поведению в общесистемном наборе кэшей из-за искусственного «разогрева» менее часто используемых данных.

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

Использование адаптивной стратегии определения размера кэша означает, что использование ресурсов вашей программы будет переменным и непредсказуемым. (Что касается как памяти, так и запросов ввода-вывода и сервера, используемых для заполнения этого кэша предварительной выборки.) Для многих серверных ситуаций это не хорошо. (Особенно на серверах HPC или DB, как это может показаться, или в среде с высокой загрузкой / высокой пропускной способностью.) Согласованность, конфигурируемость и доступность часто важнее, чем максимальное использование ресурсов. А местность ссылок обычно быстро падает, так что вы, вероятно, получите очень убывающую отдачу с большими размерами кэша. Если это будет использоваться на стороне сервера, по крайней мере, оставьте опцию для явного контроля размеров кэша и, вероятно, сделайте эту опцию по умолчанию, если не только, опцией.

1 голос
/ 09 марта 2011

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

1 голос
/ 09 марта 2011

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

  • Windows: GetProcessMemoryInfo
  • Linux: / proc / self / statm
  • OS X: task_info ()

В Windows также есть GlobalMemoryStatusEx, который дает хороший показатель доступной физической памяти.

0 голосов
/ 09 марта 2011

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

try {
  char *buf = new char[10 * 1024 * 1024]; // 10 megabytes
  free(buf);
} catch (const std::bad_alloc &) {
  // Memory allocation failed - clean up old buffers
}

Проблемы с этим подходом:

  1. Нехватка системной памяти может быть опасной и приводить к закрытию случайных приложений
  2. Лучшим решением может быть лучшее управление памятью. Если есть данные, которые можно освободить, почему они еще не были освобождены? Есть ли периодический процесс, который вы могли бы запустить для очистки ненужных данных?
0 голосов
/ 09 марта 2011

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

Вот цитата из архитектурных заметок проекта Varnish:

Очень короткий ответ: у компьютеров больше нет двух видов хранилищ.

Я бы предложил вам прочитать полный текст здесь: http://www.varnish -cache.org / trac / wiki / ArchitectNotes

Это хорошее чтение, и я верю, что ответит на ваш вопрос.

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