Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > как лимитировать память для приложения


Автор: drdeath 12.7.2009, 04:44
лимитировать или хотя-бы определить сколько памяти использует приложение интересует как линукс так и windows

Автор: GremlinProg 12.7.2009, 12:50
Цитата(drdeath @  12.7.2009,  06:44 Найти цитируемый пост)
как лимитировать память для приложения

какой именно памяти?

физическую можно "ограничить" с помощью SetProcessWorkingSetSize
в кавычках потому, что этот лимит спокойно можно обойти, используя AWE API

а вот виртуальную, в принципе не ограничить,
каждый процесс может потреблять все адресное пространство (32- или 64-битное),
можно только определить, сколько виртуальной памяти можно выделить, не расширяя файла подкачки - GetPerformanceInfo:
Цитата(PERFORMANCE_INFORMATION::CommitLimit @ MSDN)

The current maximum number of pages that can be committed by the system without extending the paging file(s). This number can change if memory is added or deleted, or if pagefiles have grown, shrunk, or been added. If the paging file can be extended, this is a soft limit.

т.е. любой вызов VirtualXXX сразу влияет на эту характеристику в процессе

хотя ни кто не мешает просто заранее отрезать кусок памяти, нужного объема, который не должен использоваться,
но это глупо )), лимит будет формальным

посмотреть текущий уровень загрузки памяти всех видов можно с помощью GlobalMemoryStatus/Ex

ps: все это касаемо windows

Автор: Vaulter 12.7.2009, 13:39
как определить:

Код

    std::pair< unsigned long long, unsigned long long >
    procinfo_GetProcessMemoryUsageBytes()
    {
#ifdef WIN32
        HANDLE  hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, procinfo_GetProcessId());
        if (hProcess)
        {
            PROCESS_MEMORY_COUNTERS tMemCounters;
            memset(&tMemCounters, 0, sizeof(tMemCounters));
            tMemCounters.cb = sizeof(PROCESS_MEMORY_COUNTERS);
            if (GetProcessMemoryInfo(hProcess, &tMemCounters, sizeof(tMemCounters)))
            {
                ::CloseHandle(hProcess);
                return ( std::make_pair( tMemCounters.WorkingSetSize, tMemCounters.WorkingSetSize) );
            }
            ::CloseHandle(hProcess);
        }
        assert(0);
        return ( std::make_pair( 0, 0) ); // Failed to query

#else // WIN32
    FILE* statm;
    unsigned long long virtual_memory_size, resident_set_size;
    int scan_status;
    statm = fopen("/proc/self/statm", "r");
    if (statm)
    {
        scan_status = fscanf(statm, "%llu %llu", &virtual_memory_size, &resident_set_size);
        fclose(statm);
        if (scan_status == 2)
        {
            long sz = sysconf(_SC_PAGESIZE);
            return ( std::make_pair( virtual_memory_size * sz, resident_set_size * sz ) );
        }
    }
        return ( std::make_pair( 0, 0) ); // Failed to query

#endif // !WIN32
    }


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

Автор: dumb 12.7.2009, 15:15
http://forum.vingrad.ru/forum/topic-200391.html

Автор: GremlinProg 12.7.2009, 15:36
да, dumb, с жобами гораздо интереснее,
только, как я понимаю, это только мониторинг, а не лимитирование,
не так ли?

Автор: dumb 12.7.2009, 17:32
не, там именно квотирование - если лимит исчерпан, то следующие попытки выделения памяти завершатся ошибкой.
с учетом того, как нонче пишут программы, это практически 100% обрушение процесса. smile

Автор: GremlinProg 12.7.2009, 18:02
Цитата(dumb @  12.7.2009,  19:32 Найти цитируемый пост)
с учетом того, как нонче пишут программы, это практически 100% обрушение процесса.

это был мой следующий вопрос ))

какой статус будет поднят при исключении?
STATUS_NO_MEMORY или что-то свое, типа ERROR_NOT_ENOUGH_QUOTA?

кстати, это лимитирование именно виртуальных ресурсов (в состоянии commited):
Цитата(JOBOBJECT_BASIC_LIMIT_INFORMATION vs JOB_OBJECT_LIMIT_PROCESS_MEMORY @ MSDN)

Causes all processes associated with the job to limit their committed memory. When a process attempts to commit memory that would exceed the per-process limit, it fails. If the job object is associated with a completion port, a JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT message is sent to the completion port.

кто пробовал (или собирается), отпишитесь, думаю интересно будет всем

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)