Будет ли Microsoft Windows 10 перераспределять память?

Вопрос или проблема

Операционные системы Linux обычно позволяют превышение объема памяти. Например, процесс может выделить 100 ГБ памяти, даже если на машине всего 8 ГБ физической памяти и нет swap.

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

Как это работает в Windows? Откажется ли Windows предоставлять процессам виртуальную память, если не сможет гарантировать, что эта память может быть обеспечена реальной памятью (физической ОЗУ или swap)?

Отвечая на свой собственный вопрос, так как никто другой не ответил.

Похоже, что Windows НЕ позволяет превышение объема памяти. Это на самом деле большая разница по сравнению с Linux.

Windows позволяет программе выделять больше (виртуальной) памяти, чем имеется ОЗУ на машине, но ТОЛЬКО если достаточно свободного места на диске, чтобы при необходимости обеспечить запрашиваемую программой виртуальную память диском.

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

Windows превышает объем стеков. Вы можете легко создать несколько потоков с пространством стека, значительно превышающим ОЗУ + swap. Следующая программа на C++20 показывает атрибуты страницы одного мегабайта стека:

#include <Windows.h>
#include <iostream>

using namespace std;

int main( int argc, char **argv )
{
    auto stackThread = []( LPVOID lpvThreadParam ) -> DWORD
    {
        ULONG_PTR stackTop, stackBottom;
        GetCurrentThreadStackLimits( &stackBottom, &stackTop );
        char const
            *pStackTop = (char *)stackTop,
            *pStackBottom = (char *)stackBottom;
        SYSTEM_INFO si;
        GetSystemInfo( &si );
        MEMORY_BASIC_INFORMATION mbi;
        auto query = [&]( char const *p ) -> char const *
        {
            if( VirtualQuery( p, &mbi, sizeof mbi ) != sizeof mbi )
                ExitProcess( EXIT_FAILURE );
            return (char *)mbi.AllocationBase;
        };
        char const *base = query( pStackBottom ), *p;
        do
        {
            cout << mbi.RegionSize / si.dwPageSize << ": ";
            unsigned n = 0;
            auto append = [&]<typename ... T>( T &&... values ) { cout << (", " + !n++); ((cout << values), ...); };
            if( mbi.State != MEM_FREE )
                if( mbi.State == MEM_COMMIT )
                    append( "выделено" );
                else if( mbi.State == MEM_RESERVE )
                    append( "резервировано" );
                else
                    append( "С: 0x", hex, mbi.State );
            if( !mbi.Protect )
                append( "недоступно" );
            else if( mbi.Protect & PAGE_GUARD )
                append( "страница защиты" );
            else if( mbi.Protect == PAGE_READWRITE )
                append( "чтение-запись" );
            else
                append( "З: 0x", hex, mbi.Protect );
            cout << endl;
            p = (char *)mbi.BaseAddress + mbi.RegionSize;
        } while( query( p ) == base && mbi.BaseAddress < pStackTop );
        return 123;
    };
    HANDLE hThread = CreateThread( nullptr, 0x100000, stackThread, nullptr, STACK_SIZE_PARAM_IS_A_RESERVATION, nullptr);
    WaitForSingleObject( hThread, INFINITE );
    CloseHandle( hThread );
    return 0;
}

Вот атрибуты стека, показанные на моем компьютере:

251:  резервировано, недоступно
2:  выделено, страница защиты
3:  выделено, чтение-запись

Как видите, большая часть стека изначально не выделена.

Ответ или решение

Будет ли Windows 10 переполнять память?

Вопрос переполнения памяти в операционных системах является ключевым аспектом их функционирования. Для начала, стоит заметить, что в отношении управления памятью Windows и Linux действуют разные подходы. В частности, Linux позволяет выделять больше памяти, чем фактически доступно на устройстве, что позволяет процессам, например, выделять 100 ГБ, даже когда в системе всего 8 ГБ оперативной памяти. Это возможно благодаря механизму, который допускает выделение виртуальной памяти в объеме, превышающем физическую память, до тех пор, пока не происходит фактическое использование этой памяти.

Принципы управления памятью в Windows

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

Оператор OOM в Windows

В отличие от Linux, где используется OOM (Out Of Memory) – убийца для освобождения памяти за счет завершения процессов, Windows не имеет аналогичного механизма. Вместо этого, система стремится сохранить стабильность, отклоняя запросы на выделение памяти, когда такая память не может быть обеспечена. Это позволяет избежать критических сбоев в работе приложений и системы в целом.

Ограничения на уровне приложений

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

Стековый переполнение в Windows

Однако Windows действительно «переполняет» стек, что позволяет создавать потоки с большим объемом стекового пространства, чем физическая память плюс своп. Пример кода на C++ показывает, что, когда создается поток, стек может инициализироваться с незарезервированной памятью, при этом инициализация памяти происходит по мере необходимости (ленивая инициализация). Это означает, что большая часть стека может оставаться «неактивной» до момента, пока она не будет фактически использована.

Заключение

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

Ключевые выводы:

  • Windows 10 требует достаточного свободного пространства на диске для выделения виртуальной памяти.
  • OOM-контроль в Windows отличается от Linux, что влияет на поведение приложений в условиях нехватки памяти.
  • Стековая память имеет свои особенности при выделении и использовании, что следует учитывать при программировании.

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

Оцените материал
Добавить комментарий

Капча загружается...