Предотвращение зависания тяжелого процесса в файле подкачки

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

Вопрос

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

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

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

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

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

Решение

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

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

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

Резюме. Регулярно прикасайтесь к каждой странице процесса, на странице за раз.

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

65536 страниц в 4 ГБ, 49152 страницы в 3 ГБ, 32768 страниц в 2 ГБ. Разделите время простоя (ночное время простоя) на то, как часто вы хотите (пытаетесь) попасть на каждую страницу.

BYTE *ptr;

ptr = NULL;
while(TRUE)
{
    __try
    {
        BYTE b;

        b = *ptr;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        // ignore, some pages won't be accessible
    }

    ptr += sizeofVMPage;

    Sleep(N * 1000);
}

Вы можете получить значение sizeOfVMPage из значения dwPageSize в возвращенном результате из GetSystemInfo ().

Не пытайтесь избегать обработчика исключений, используя if (! IsBadReadPtr (ptr)), потому что другие потоки в приложении могут одновременно изменять защиту памяти. Если вы отстегнетесь из-за этого, почти невозможно определить причину (это, скорее всего, будет не повторяемое состояние гонки), поэтому не тратьте время на это.

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

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

Еще одна вещь, которую необходимо обеспечить, - это локализация ваших данных.

Другими словами:вам действительно нужны все 300 МБАЙТ памяти, прежде чем вы сможете что-либо сделать?Можно ли изменить используемые вами структуры данных таким образом, чтобы любой конкретный запрос мог быть удовлетворен всего несколькими мегабайтами?

Например

  • если ваши 300 МБ оперативной памяти содержат данные распознавания лиц.Могут ли внутренние данные быть организованы таким образом, чтобы данные о мужском и женском лице хранились вместе?Или большие носы отделены от маленьких?

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

  • если это собственный движок базы данных в памяти, могут ли данные быть лучше проиндексированы / кластеризованы, чтобы не требовать такого большого количества обращений к странице памяти?

  • если это текстуры изображений, могут ли обычно используемые текстуры располагаться рядом друг с другом?

Вам действительно нужны все 300 МБАЙТ памяти, прежде чем вы сможете что-либо сделать?Вы не можете запросить обслуживание без ВСЕ эти данные вернулись в память?


В противном случае: запланированное задание на 6 часов утра, чтобы разбудить его.

С точки зрения стоимости, самое дешевое и простое решение - просто купить больше оперативной памяти для этого сервера, а затем полностью отключить файл подкачки. Если вы используете 32-битную Windows, просто купите 4 ГБ оперативной памяти. Тогда все адресное пространство будет обеспечено физической памятью, и файл подкачки ничего не будет делать.

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