Потребление памяти неуправляемым приложением VC++ на сервере Windows

Хорошо, у меня есть очень большое многопоточное неуправляемое приложение (сервер) C++, которое работает на сервере Windows 2003. В нем размещаются сеансы для 20-50 одновременных пользователей, выполняющих всевозможную бизнес-логику ... Иногда он может использовать очень большой объем памяти из-за таких вещей, как кэширование объектов / сеансов из-за того, что пользователи имеют большое количество окон, открытых в клиентах. (каждое окно имеет отдельный сеанс сервера.

Обычно мы наблюдаем потребление более 5-600 МБ физической памяти и 5-600 МБ виртуальной памяти. Как только дело доходит до этого момента, мы, кажется, начинаем получать ошибки «нехватки памяти».

Теперь я знаю, что Windows начнет отказываться от страниц, когда почувствует необходимость освободить физическую память, а также, что приложения win32 обычно могут выделить максимум 4 ГБ памяти, на самом деле только с 2 ГБ доступной для фактическое использование приложением адресного пространства в «пользовательском режиме», и тем более после загрузки других библиотек ... Я не уверен, что использование памяти в «пользовательском режиме» - это то, что отображается в диспетчере задач. ..

Так или иначе, мой настоящий вопрос:

Как я могу узнать, сколько памяти пользовательского режима имеет доступ к моему приложению и сколько памяти было использовано в любой момент времени (желательно извне приложения, то есть с помощью какого-либо инструмента управления Windows)?

[править] Посмотрев на Process Explorer и на веб-сайт, похоже, что значение Virtual Size - это значение того, к какому объему памяти приложение имеет доступ.

Ответов (3)

Решение

Звучит как случай для Process Explorer, бесплатной утилиты от Microsoft SysInternals :

альтернативный текст
(источник: microsoft.com )

Описание:

Вы когда-нибудь задумывались, в какой программе открыт тот или иной файл или каталог? Теперь вы можете это узнать. Обозреватель процессов показывает вам информацию о том, какие дескрипторы и процессы DLL были открыты или загружены.

Экран Process Explorer состоит из двух подокон. В верхнем окне всегда отображается список активных в данный момент процессов, включая имена их собственных учетных записей, тогда как информация, отображаемая в нижнем окне, зависит от режима, в котором находится Process Explorer: если он находится в режиме дескриптора, вы увидите указывает, что процесс, выбранный в верхнем окне, был открыт; если Process Explorer находится в режиме DLL, вы увидите DLL и файлы с отображением памяти, загруженные процессом. В Process Explorer также есть мощная возможность поиска, которая быстро покажет вам, у каких процессов открыты определенные дескрипторы или загружены библиотеки DLL.

Уникальные возможности Process Explorer делают его полезным для отслеживания проблем с версиями DLL или обработки утечек, а также для понимания того, как работают Windows и приложения.


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

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

альтернативный текст

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

неуправляемый C++

#include <windows.h>
#include <stdio.h>
#include <psapi.h>

void PrintMemoryInfo( DWORD processID )
{
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS pmc;

    // Print the process identifier.

    printf( "\nProcess ID: %u\n", processID );

    // Print information about the memory usage of the process.

    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                             PROCESS_VM_READ,
                             FALSE, 
                             processID );
    if (NULL == hProcess)
        return;

    if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
    {
        printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
        printf( "\tYour app's PEAK MEMORY CONSUMPTION: 0x%08X\n", 
                  pmc.PeakWorkingSetSize );
        printf( "\tYour app's CURRENT MEMORY CONSUMPTION: 0x%08X\n", pmc.WorkingSetSize );
        printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", 
                  pmc.QuotaPeakPagedPoolUsage );
        printf( "\tQuotaPagedPoolUsage: 0x%08X\n", 
                  pmc.QuotaPagedPoolUsage );
        printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", 
                  pmc.QuotaPeakNonPagedPoolUsage );
        printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", 
                  pmc.QuotaNonPagedPoolUsage );
        printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); 
        printf( "\tPeakPagefileUsage: 0x%08X\n", 
                  pmc.PeakPagefileUsage );
    }

    CloseHandle( hProcess );
}

int main( )
{
  PrintMemoryInfo( GetCurrentProcessId() );

    return 0;
}

Вы написали:

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

Посмотрите эту статью (написана создателем Process Explorer доктором Марком Руссиновичем).

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