Разработка и отладка приложений mem-hogging на C # - PullRequest
12 голосов
/ 29 апреля 2009

У меня есть приложение на C #, которое должно связываться с 32-битной библиотекой, а также должно использовать максимально возможный объем памяти (приложение для обработки изображений); мы запускаем приложение на рабочих столах XP64, поэтому мы используем WOW64, ориентируясь на сборки в Visual Studio для x86 (и проводя editbin /largeaddressaware после сборки). Мы столкнулись с несколькими проблемами:

  • Во встроенном отладчике Visual Studio мы можем использовать только 2 ГБ памяти (~ 1,5 ГБ на приложение, плюс накладные расходы)

  • При запуске из командной строки приложение может видеть 3 ГБ памяти, но документы Microsoft, похоже, говорят, что мы должны видеть 4 ГБ.

Может кто-нибудь сказать мне, как получить приложение WOW64 C #, чтобы увидеть полные 4 ГБ, которые должна иметь платформа?

Кроме того, кто-нибудь может сказать мне, как заставить отладчик Visual Studio (VS 2008, также известный как VS90) подчиняться биту /largeaddressaware и прекратить ограничение памяти приложения до 2 ГБ?

Я вижу такое же поведение в VS80 и VS90; Также нет разницы между .NET Framework 3.5, 3.0 и 2.0. Вот тривиальная программа на C #, иллюстрирующая проблемы; сборка для x86, editbin /largeaddressaware, затем запуск во встроенном отладчике по сравнению с запуском из командной строки, чтобы увидеть разницу в доступной памяти для C #.

namespace MemoryAllocTest
{
class Program
{
    static void Main(string[] args)
    {
        const int allocSize = 1024 * 1024;
        List<byte[]> myMem = new List<byte[]>();
        UInt64 totalAlloc = 0;

        while (true)
        {
            myMem.Add(new byte[allocSize]);
            totalAlloc += allocSize;
            Console.WriteLine("{0} allocs: {1}MB total", 
             myMem.Count, totalAlloc / (1024 * 1024));
        }
    }
}
}

Ответы [ 6 ]

5 голосов
/ 30 апреля 2009

Может кто-нибудь сказать мне, как заставить отладчик Visual Studio (VS 2008, также известный как VS90) подчиняться биту / largeaddressaware и прекратить ограничение памяти приложения до 2 ГБ?

Это требует двух шагов - оба в свойствах проекта:

  • на вкладке событий сборки установите шаг после сборки для запуска editbin / largeaware $ (TargetPath)
  • на вкладке отладки снимите флажок Включить хостинг Visual Studio процесс

С этими двумя шагами ваша примерная программа работала до 3045 МБ

3 голосов
/ 30 апреля 2009

Спасибо всем, кто откликнулся; этот сайт действительно потрясающий!

Кажется, что в WOW64 мы действительно достигаем 4 ГБ пользовательского пространства, но мне кажется (слегка образованное предположение), что накладные расходы сборщика мусора (или, возможно, запас прочности) становятся значительными по мере роста памяти, выделяемой управляемым кодом. Запустив мое тестовое приложение на WOW64 (командная строка с LARGEADDRESSAWARE), я получаю общий объем ресурсов 3175 МБ; работая на машине с WIN32 XP с набором параметров 4GT, я получаю общее выделение 2857 МБ, поэтому полный гигабайт дополнительной памяти в пользовательском режиме дает увеличение только на ~ 318 МБ на уровне приложения C #!

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

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

2 голосов
/ 30 апреля 2009

Я собрал ваше простое приложение из этого поста, разбил его и прикрепил к нему WinDbg.

! Address -summary покажет вам эффективное адресное пространство пользовательского режима для процесса.

0:003> !address -summary
 TEB fffdd000 in range fffdb000 fffde000
 TEB fffda000 in range fffd8000 fffdb000
 TEB fffd7000 in range fffd5000 fffd8000
 TEB fffaf000 in range fffad000 fffb0000
 ProcessParametrs 004c2b40 in range 004c0000 00535000
 Environment 004c1978 in range 004c0000 00535000

-------------------- Usage SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots) Pct(Busy)   Usage
   e7d2e000 ( 3798200) : 90.56%    98.77%    : RegionUsageIsVAD
   1547b000 (  348652) : 08.31%    00.00%    : RegionUsageFree
    2887000 (   41500) : 00.99%    01.08%    : RegionUsageImage
     3ff000 (    4092) : 00.10%    00.11%    : RegionUsageStack
          0 (       0) : 00.00%    00.00%    : RegionUsageTeb
     1c0000 (    1792) : 00.04%    00.05%    : RegionUsageHeap
          0 (       0) : 00.00%    00.00%    : RegionUsagePageHeap
       1000 (       4) : 00.00%    00.00%    : RegionUsagePeb
          0 (       0) : 00.00%    00.00%    : RegionUsageProcessParametrs
          0 (       0) : 00.00%    00.00%    : RegionUsageEnvironmentBlock
       **Tot: ffff0000 (4194240 KB)** Busy: eab75000 (3845588 KB)

-------------------- Type SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots)  Usage
   1547b000 (  348652) : 08.31%   : <free>
    2aa3000 (   43660) : 01.04%   : MEM_IMAGE
    1f6a000 (   32168) : 00.77%   : MEM_MAPPED
   e6168000 ( 3769760) : 89.88%   : MEM_PRIVATE

-------------------- State SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots)  Usage
   db838000 ( 3596512) : 85.75%   : MEM_COMMIT
   1547b000 (  348652) : 08.31%   : MEM_FREE
    f33d000 (  249076) : 05.94%   : MEM_RESERVE

Largest free region: Base fbfc0000 - Size 03fed000 (65460 KB)

На основании данных: ffff0000 (4194240 КБ) у нас есть 4 ГБ эффективного пространства пользовательского режима.

Также наш самый большой свободный блок составляет 65 460 КБ, что означает, что мы должны иметь возможность выделять больше памяти.

2 голосов
/ 29 апреля 2009

Какую точную версию .NET вы используете? Этот отчет о подключении касается примерно той же проблемы (насколько я могу судить), замеченной в .NET 2.0, но исправленной в .NET 2.0SP1.

Если на ваших машинах x64 нет 2.0SP1 (или более поздней версии), стоит попробовать ...

2 голосов
/ 29 апреля 2009

С Microsoft :

Виртуальное адресное пространство процессов и приложений по-прежнему ограничено 2 ГБ, если в / 3GB не используется ключ файл Boot.ini. Когда физическое Объем оперативной памяти в системе превышает 16 ГБ и ключ / 3GB используется, операционная система будет игнорировать дополнительную оперативную память пока не будет удален ключ / 3GB. это из-за увеличенного размера ядро требуется для поддержки большего Записи таблицы страниц. Предположение сделал что бы администратор скорее не потеряйте функциональность / 3GB тихо и автоматически; следовательно, это требует от администратора явно измените этот параметр. Переключатель / 3GB выделяет 3 ГБ виртуальное адресное пространство для приложение, которое использует IMAGE_FILE_LARGE_ADDRESS_AWARE в заголовок процесса. Этот переключатель позволяет заявки на адрес 1 ГБ дополнительное виртуальное адресное пространство выше 2 ГБ.

1 голос
/ 29 апреля 2009

Можете ли вы опубликовать там, где подразумевается, что вы видите все 4 ГБ? Ох, может быть, здесь: Интересная информация по этой ссылке

Различия в адресуемой памяти

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

* 32-bit applications on 32-bit platforms can address up to 2 GB
* 32-bit applications built with the /LARGEADDRESSAWARE:YES linker flag

в 32-битной Windows XP или Windows Server 2003 со специальной загрузочной опцией / 3gb Можно адресовать до 3 ГБ. это ограничивает ядро ​​только 1 ГБ что может вызвать некоторые драйверы и / или услуги не работают.

* 32-bit applications built with the /LARGEADDRESSAWARE:YES linker flag

в 32-разрядных версиях Windows Vista, и на 32-битных версиях Windows Кодовое имя сервера "Longhorn" работает системы, могут обращаться к памяти до номер, указанный при загрузке элемент данных конфигурации (BCD) IncreaseUserVa. IncreaseUserVa может имеют значение в диапазоне от 2048 г. по умолчанию 3072 (что соответствует объем памяти, настроенный / 3gb опция загрузки в Windows XP). остаток 4 ГБ выделяется на ядро и может привести к сбою конфигурации драйверов и служб.

Дополнительные сведения о BCD см. В разделе Данные конфигурации загрузки на MSDN.

* 32-bit applications on 64-bit platforms can address up to 2 GB, or up

до 4 ГБ с флагом компоновщика / LARGEADDRESSAWARE: YES. * 64-битные приложения используют 43 бит для адресации, что обеспечивает 8 ТБ виртуальный адрес для приложений и 8 ТБ зарезервирован для ядра.

Так что да, похоже, вы должны (на цели XP64) увидеть 4 ГБ.

...