我有一个由许多C++类组成的大型框架。在运行时,有没有一种方法可以使用任何工具来跟踪正在创建和存在的所有C++对象?
例如,在某个时间t1,可能应用程序具有对象A1、A2和B3,但在时间t2,它具有A1、A4、C2等。
这是一个跨平台的框架,但我熟悉在Linux、Solaris和(可能)Mac OS X上的工作。
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> {
}
自动生成每个类类型的计数器。
我假设您只计算堆上的对象。如果是这种情况,您可以通过将它们替换为一些自定义宏来记录所有对new和delete的调用。
我们已经开发了这样一个自定义日志记录工具。主要目的是跟踪内存泄漏,但也可以用于查找任何特定时间点的对象数量。例如,
#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会在每行开头自动添加时间戳。该行包括类名、文件名、行号、函数名和大小。
一个实用程序解析日志文件并生成图表,显示任何时间的对象数量、总大小等。
当然,您必须使用宏替换每个new/delete调用。这可能需要相当多的工作。
我自己没有使用过,但Massif可能是你正在寻找的工具。 http://valgrind.org/info/tools.html
这只适用于 Solaris,但如果您可以使用 dtrace 选项,可以跟踪每个类的构造函数和析构函数调用次数,并在一定间隔内打印出来。这将需要设置所有进入/返回块的一定量工作,但我怀疑 dtrace 脚本可以自动生成。
SomeObject
,则globalSomeObjectCounter
和globalSomeObjectParentCounter
都会增加一个,这正是应该的。 - Andreas Brinck