Предотвратите рабочий набор памяти, минимизируют в Консольном приложении?

Я хочу предотвратить рабочий набор памяти, минимизируют в Консольном приложении. В приложении Windows я могу сделать путем переопределения сообщений SC_MINIMIZE. Но, как я могу прервать SC_MINIMIZE в консольном приложении? Или, я могу предотвратить рабочий набор памяти, минимизируют другими путями?

Я использую C++ Visual Studio 2005 года. У кого-то есть некоторая проблема, и решение не приятно. :( http://www.eggheadcafe.com/software/aspnet/30953826/working-set-and-console-a.aspx

Заранее спасибо.

6
задан P-P 25 January 2010 в 03:59
поделиться

6 ответов

На самом деле для этого не требуется никакого стороннего программного обеспечения - планировщик заданий Win7 может инициировать запланированную задачу всякий раз, когда он видит определенный тип события, и необработанное исключение записывается в журнал событий. Одно из встроенных действий - «Отправить сообщение электронной почты», поэтому вы получили все свое решение в ОС

-121--4998314-

Я думал, что компиляторы должны быть умно делать подобные вещи. Сделать мы должны все еще сделать это?

Вы, вероятно, правы, что МОНЕТА В ПЯТЬ ЦЕНТОВ заботится о нем, но если бы этот раздел - так очень важное исполнение, пробование и определение эффективность не причинили бы боль.

-121--4632476-

Обрезка рабочего набора может быть предотвращена только блокировкой страниц в памяти либо прямой блокировкой с помощью VirtureLock , либо отображением памяти в AWE . Но обе операции имеют чрезвычайно высокие привилегии и требуют, чтобы приложение запускалось под учетной записью, которой предоставляется «Блокировка страниц в памяти» , см. Как включить параметр блокировки страниц в памяти . По умолчанию никто, а не администраторы вен, не имеют этой привилегии.

Технически, это ответ, который вы ищете (пропуская «незначительные» детали того, как идентифицировать регионы для блокировки). Но ваш вопрос указывает на то, что вы находитесь на совершенно неправильном пути.

Обрезка набора Working - это то, что происходит часто и не имеет серьезных побочных эффектов. Вы, скорее всего, путаете обрезку с пейджингом памяти, но они являются различными фазами времени жизни страницы памяти. Обрезка происходит, когда ОС удаляет отображение страницы из процесса и помещает страницу в резервный список. Это очень быстрая и простая операция: страница добавляется в список ожидания и соответствующим образом помечается pte . Операция ввода-вывода не выполняется, физическое содержимое ОЗУ не изменяется. Когда и если процесс снова обращается к обрезанной странице, произойдет мягкий отказ . Промах TLB вызовет переход в область ядра, ядро обнаружит страницу в резервном списке и повторно назначит ее процессу. Быстрая, быстрая, простая операция ввода-вывода не выполняется, а содержимое ОЗУ для страницы не изменяется. Таким образом, процесс, в котором весь рабочий набор обрезан, будет восстанавливать весь активный набор довольно быстро (микросекунды), если он продолжает ссылаться на страницы.

Только в том случае, когда ОС требуются новые страницы для ее списка свободных страниц, она будет искать в резервном списке, брать самую старую страницу и фактически заменять ее на диск. В этой ситуации действительно происходит IO, и содержание ОЗУ обнуляется. При повторном обращении процесса к странице произойдет жесткий отказ . Промах TLB разбудит ядро, это проверит список pte's и теперь произойдет ошибка «реальной» страницы: выделена новая свободная страница, содержимое считывается с диска, а затем страница выделяется процессу и выполнение возобновляется из местоположения промаха TLB.

Как видите,существует огромная разница между обрезкой рабочего набора и заменой страницы давления памяти. Если приложение консоли обрезано, не потеть над ним. Вы нанесете неизмеримый больший ущерб работоспособности системы, заблокировав страницы в памяти. И btw, вы также делаете подобный плохой опыт пользователя, отказываясь минимизировать, когда его просят, только потому, что вы неправильно понимаете жизненный цикл страницы.

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

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

6
ответ дан 9 December 2019 в 20:43
поделиться

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

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

1
ответ дан 9 December 2019 в 20:43
поделиться

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

2
ответ дан 9 December 2019 в 20:43
поделиться

SetProcessWorkingSetSize(Ex) или используйте VirtualLock в диапазоне, который вы хотите сохранить в физической памяти.

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

3
ответ дан 9 December 2019 в 20:43
поделиться

Вы можете использовать очень подлый / взлом для этого, что может быть вашим единственным способом:

SetConsoleTitle("MyConsole"); //at creation
//... 
HWND hWnd = FindWindow(NULL,"MyConsole"); //when it would minimize
ShowWindow(hWnd,SW_MAXIMIZE);

Вы сможете даже скриться с некоторыми из свойств окон с использованием HWND

0
ответ дан 9 December 2019 в 20:43
поделиться

Как насчет отключения минимизации в системном меню консоли?

HWND hwnd = GetConsoleWindow(void);
HMENU hmenu = GetSystemMenu(hwnd, FALSE);
EnableMenuItem (hmenu, SC_MINIMIZE, MF_DISABLED | MF_BYCOMMAND);

Вы также можете попробовать отключить кнопку минимизации на вашем консольном окне.

HWND hwnd = GetConsoleWindow(void);
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, lStyle & ~WS_MINIMIZEBOX);
0
ответ дан 9 December 2019 в 20:43
поделиться
Другие вопросы по тегам:

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