.NET API для определения фрагментации виртуальных машин - PullRequest
1 голос
/ 22 января 2010

Существует ли .NET API для получения подробной информации об использовании виртуальных машин? Меня особенно интересует, насколько фрагментировано мое адресное пространство.

Спасибо!

Ответы [ 5 ]

1 голос
/ 22 января 2010

Функции API Windows, которые могут дать вам некоторое представление об этом, - это VirtualQueryEx () для перечисления разделов виртуальной памяти и обнаружения неиспользуемого пространства, GetProcessHeaps () для поиска кучи, созданной внутри процесса, и HeapWalk () для обнаружения как используются блоки в каждой куче.

Это будет непросто, особенно HeapWalk () - это хлопотная функция в работающей программе. Вам следует взглянуть на утилиту SysInternals VMMap , которая обеспечивает отличную диагностику виртуальной памяти.

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

1 голос
/ 22 января 2010

Краткий ответ: нет. Для этого вам нужно подключиться к Win32 API. Я действительно не знаю, какой API-вызов вы бы использовали ...

Быстрый поиск по http://www.pinvoke.net привел меня к этому:

[DllImport("coredll.dll", SetLastError=true)]
static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);

Но структура MEMORYSTATUS, похоже, не содержит всей необходимой информации (только использование физической и виртуальной памяти и другая информация).

Вам нужно покопаться в MSDN, чтобы найти нужный метод.

0 голосов
/ 06 апреля 2011

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

HANDLE heap = GetProcessHeap();
PROCESS_HEAP_ENTRY entry;
memset(&entry, 0, sizeof(entry));
unsigned long size = 0;
while(HeapWalk(heap, &entry)) {
    if(entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) {
        size += entry.cbData;
    }
}

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

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

0 голосов
/ 16 марта 2010

Вам действительно нужно зайти в Win32 / Win64 API, чтобы получить эту информацию на уровне страницы. Более подробно, и вам нужно знать внутреннюю работу той кучи, которую вы просматриваете, будь то куча C, куча Win32, куча небольших объектов CLR или куча больших объектов CLR.

Однако вы можете использовать Virtual Memory Validator (коммерческий, но бесплатный), чтобы визуализировать пространство виртуальной памяти, а также исследовать пространство памяти страница за страницей и абзац за абзацем. Сначала посмотрите на визуальные эффекты, поскольку это позволяет легко увидеть общие проблемы и тенденции. Затем посмотрите подробную информацию на страницах и в абзацах, когда решите, какие области памяти проблематичны.

Вот статья в блоге, описывающая, что такое страницы и пункты .

0 голосов
/ 22 января 2010

Такой вызов не имеет смысла в управляемом мире, поскольку разные хосты CLR могут обрабатывать разные вещи (например, обычный хост приложения или SQL Server). И не забывайте, что GC может что-то изменить, так что фрагментация на самом деле не проблема, если GC сжимает кучу.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...