C ++: Как подсчитать все экземпляры объектов во время выполнения? - PullRequest
8 голосов
/ 28 апреля 2010

У меня есть большая структура, состоящая из множества классов C ++. Есть ли способ использовать какие-либо инструменты во время выполнения, чтобы отследить все объекты C ++, которые создаются и существуют в настоящее время?

Например, в определенный момент времени t1, возможно, приложение имеет объекты A1, A2 и B3, но в момент времени t2 оно имеет A1, A4, C2 и т. Д.?

Это кроссплатформенный фреймворк, но я знаком с работой в Linux, Solaris и (возможно) Mac OS X.

Ответы [ 5 ]

10 голосов
/ 28 апреля 2010

Вы можете внедрить код в деструктор и конструктор объектов, которые вы хотите считать:

SomeObject::SomeObject() {
   ++globalSomeObjectCounter;
}

SomeObject::~SomeObject() {
   --globalSomeObjectCounter;
}

Не забудьте увеличить счетчик в всех конструкторах (копировать конструкторы и т.д.)

РЕДАКТИРОВАТЬ: В этой ситуации можно использовать странно повторяющийся шаблон:

template <typename T>
struct Counter
{
    Counter() {++counter;}
    virtual ~Counter() {--counter;}
    static int counter;
};
template <typename T> int Counter<T>::counter(0);

и затем:

class SomeObject : public Counter<SomeObject> {
}

для автоматического создания счетчика для каждого типа класса.

1 голос
/ 28 апреля 2010

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

Мы разработали такую ​​специальную систему регистрации. Основная цель состояла в том, чтобы отследить утечки памяти, но ее также можно использовать для определения количества объектов в любой конкретный момент времени. Например,

#define MY_NEW_OBJECT(a, T) \
    a = new T;              \
    MY_LOGGING((LM_DEBUG, "[NEW OBJ ] 0x%08X(%s), %4d bytes. %-20s - %-40s - %4d\n", a, #T,  \
    sizeof(T), __FILE__, __func__, __LINE__));

MyClass* myObj;
MY_NEW_OBJECT(myObj, MyClass);

MY_LOGGING автоматически добавляет метку времени в начале каждой строки. Строка содержит имя класса, имя файла, номер строки, имя функции и размер.

Утилита анализирует файл журнала и генерирует графики, показывающие количество объектов, общий использованный размер и т. Д. В любое время.

Конечно, вы должны заменять все новые / удалять вызовы макросами. Что может быть совсем немного работы.

0 голосов
/ 28 апреля 2010

Это только Solaris, но если это опция, вы можете использовать dtrace для отслеживания количества вызовов конструктора и деструктора для каждого из ваших классов и распечатывать его с интервалом. Это потребует определенного объема работы для настройки всех блоков ввода / возврата, но я подозреваю, что сценарий dtrace может быть сгенерирован автоматически.

0 голосов
/ 28 апреля 2010

Создайте специальный базовый класс, эквивалентный Java-объекту, и сделайте так, чтобы каждый класс был производным от него. Затем в этот класс поместите операции глобального счетчика, предложенные Андреасом Бринком, в конструктор / деструктор соответственно. В дополнение к обеспечению того, что производный объект учитывается только как один объект, это означает, что вам нужно только инструмент 1 конструктор и 1 деструктор. Хотя, конечно, недостатком является то, что вам нужно немного изменить определение каждого класса ...

0 голосов
/ 28 апреля 2010

Я не использовал его самостоятельно, возможно, Massif - это инструмент, который вы ищете. http://valgrind.org/info/tools.html

...