2011-02-04 1 views
3

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

В диспетчере задач я смотрю в единственном столбце памяти «Память (частный рабочий набор)». В Process Explorer я просматриваю столбец «Private bytes», потому что он поднимается, а значение в «Рабочем наборе» - нет.

Теперь, конечно, Process Explorer является правильным, потому что после нескольких распределений мое приложение выходит из строя с ошибкой Исключение из памяти. Вопрос в том, Почему диспетчер задач неверно описывает использование памяти в приложении? Не только это, но и неверно отражает глобальную свободную память системы (график на вкладке «Производительность» остается постоянным).

Мой код не нужен, но здесь он для полноты. Он показывает пустое окно, содержащее большой массив. При нажатии любой клавиши окно закрывается и открывается новый, удерживая новый массив. Произошло старое окно, возможно, из-за ошибки в библиотеке GUI qt4dotnet.

using System; 
using com.trolltech.qt.gui; 

namespace LeakTest 
{ 
    class Test : QWidget 
    { 
     public byte[] Data = new byte[1000 * 1000 * 100]; 

     public Test() 
     { 
      show(); 
      GC.Collect(); // so measurements are more accurate 
     } 

     protected override void keyPressEvent(QKeyEvent arg__1) 
     { 
      disposeLater(); 
      new Test(); 
     } 

     [STAThread] 
     static void Main(string[] args) 
     { 
      QApplication.initialize(args); 

      new Test(); 

      QApplication.exec(); 
     } 
    } 
} 

ОС: Windows 7

Интересное примечание: когда я делаю "Data" 2D-зубчатыми массив размеров [1000 * 1000 * 100][1], Диспетчер задач делает отчет повышения использования памяти.

+1

Я бы проголосовал против использования диспетчера задач/Process Explorer для поиска утечек .NET Memory.Узумно, я использую [ANTS Memory Profiler] (http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/) и даже с помощью такого специализированного инструмента довольно сложно найти утечки , У меня не было бы шанса когда-либо найти утечку в прошлом, если бы я просто использовал диспетчер задач. –

+1

Страницы, которые никогда не использовались, не нуждаются в какой-либо поддержке, так как они могут быть только при первом доступе. Поэтому они считаются частными байтами, но не нуждаются в ОЗУ и не являются частью рабочего набора. – CodesInChaos

+0

@CodeInChaos: ах, это многое объясняет. –

ответ

6

Это две совершенно разные меры памяти. Рабочий набор - это объем оперативной памяти вашей программы. Это постоянно меняющееся число и зависит от того, сколько ОЗУ требуется другим процессам. Вы не можете исчерпать RAM, Windows делает RAM доступным для вас путем замены отображаемых страниц на файл подкачки.

Частные байты - это сумма виртуальная память, используемая вашей программой, которая не используется ни при каких других процессах. На 32-битной машине у вас есть 2 гигабайта виртуальной памяти. Он должен делиться между кодом и данными. Вы получаете OOM, когда в адресном объеме виртуальной памяти недостаточно места, чтобы соответствовать запрошенному распределению. Да, это более точное число.

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

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

1

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

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

+1

Да, профайлер памяти :-) –

+1

@ Действительно! И, конечно же, в системе GC, такой как .net, даже с помощью блестящего инструмента можно проследить за ними. –

+0

@Uwe Keim: Да, я действительно использовал dotTrace Memory Profiler, но я не мог понять, что он мне говорит (он становится очень сложным, так как я использую привязки Java для библиотеки C++ через .NET). Поэтому я попытался понять как можно больше без профайлера. И я наткнулся на такое необъяснимое поведение, поэтому я разместил вопрос. Я, вероятно, отправлю еще один вопрос для профилировщика. –