С#: использование памяти для объекта

Есть ли способ узнать, сколько памяти используется для определенного объекта? Например, Список. Принимая во внимание все, например, интернирование строк и все, что выполняется средой компилятора/среды выполнения/независимо.

Ответ 1

Вам действительно нужно будет точно определить, что вы имели в виду, "сколько памяти используется для определенного объекта". Например, вы могли бы иметь в виду "если бы этот объект был собран мусором, сколько бы он был освобожден" - или вы могли бы означать, "сколько памяти делает этот объект и все, что он затрагивает".

Хорошей иллюстрацией является ваша интерпретация строк. Предположим, вы это сделали:

List<string> internedStrings = new List<string>();
List<string> nonInternedStrings = new List<string>();
for (int i=0; i < 1000; i++)
{
    string tmp = new string(' ', i+1);
    nonInternedStrings.Add(tmp);
    tmp = tmp.Intern();
    internedStrings.Add(tmp);
}

Действительно ли nonInternedStrings занимает больше памяти, чем internedStrings? Если internedStrings собирался сбор мусора, он не освобождал бы столько памяти, но если бы internedStrings никогда не создавался (в том числе и не интернировал каждый из его элементов), тогда больше памяти не требовалось бы.

Если вы можете уточнить, что именно вы имеете в виду, мы сможем вам помочь. Это сложный вопрос.

Ответ 2

ANTI Memory Profiler описывает потребление памяти в .NET-коде. У меня были отличные результаты с ним в прошлом.

Ответ 3

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

Ответ 4

Вы пробовали CLR Profiler 2.0?