Как зарезервировать память для моего приложения и оставить указанное количество оставшимся? - PullRequest
8 голосов
/ 24 декабря 2011

Я планирую приложение, которое будет включать в себя загрузку множества картинок за один раз и, следовательно, потребует большой кусок памяти.Например, я мог бы создать сразу 50 объектов изображений, занимая всего 1 ГБ ОЗУ.Но когда пользователь загружает еще 20 изображений, я хотел бы убедиться, что объем памяти уже зарезервирован и готов.

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

Так, например, если на компьютере установлено 2048 МБ ОЗУ, а также опциянастроено оставить 50 МБ свободными для других приложений, и уже 10 МБ ОЗУ используется другими приложениями, тогда для моего приложения должно быть зарезервировано 2048-50-10 = 1988 МБ.

Проблема, которую я предвиделПредположим, пользователь открывает другое приложение, которое требует 1 ГБ.Мое приложение должно поймать это и уменьшить себя.

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

Ответы [ 2 ]

8 голосов
/ 24 декабря 2011

+ 1 за упоминание Sertac о том, как SQL Server использует линию выделения памяти, которая ему нужна, но освобождает память, когда Windows жалуется.

Приложения могут получать жалобы Window, используя CreateMemoryResourceNotification:

hLowMemory := CreateMemoryResourceNotification(LowMemoryResourceNotification);

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

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

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

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

7 голосов
/ 24 декабря 2011

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

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

Если вы используете ограниченные ресурсы, убедитесь, что вы используете FastMM и включите LARGE_ADDRESS_AWAREдля вашего приложения, чтобы вы получили 4 ГБ адресного пространства при работе в 64-битной ОС.

...