How to profile the memory consumption by a set of C++ classes?
I am trying to figure out the memory consumption by my (C++) program using gprof. The program does not have a gui, it is entirely cli based.
Now, I am new to gprof, so I read a few tutorials, that taught me how to run gprof and spot time consumption.
However, I need to find out the memory consumption by a specific set of classes.
Say there is a program with many types, A, ..., Z
. No开发者_如何学运维w I want to run my program and see how many accumulated memory was used by objects of the classes A, E, I, O, U
(for example).
Have you guys any ideas or pointers how I could approach this task?
I am not exclusively considering gprof, I am open for any (fos) software that gets the job done.I have, of course, searched both google and stackoverflow.com for any answer to this problem, but either I use the wrong keywords or there is nobody having this problem out there.
Edit: Suggestions about doing this manually are obvious. Of course I could code it into the application, but its about a great deal of classes I would rather not change. Also, I want to have the total memory consumption, so I cannot only count all created objects, because I would have to track the size of the object individually.
Edit2: I went with a modification of DeadMG's suggestion, which I only have to inherit from. It works pretty well, so, if anybody has as similar problem, try this.
class GlobalObjectCounter {
public:
struct ClassInfo {
unsigned long created;
unsigned long destroyed;
unsigned short size;
ClassInfo() : created(0), destroyed(0), size(0) {}
ClassInfo(unsigned short _size) : created(0), destroyed(0), size(_size) {}
void fmt(std::ostream& os) {
os << "total: " << (this->created) << " obj = " << (this->created*this->size) << "B; ";
os << "current: " << (this->created-this->destroyed) << " obj = " << ((this->created-this->destroyed) * this->size) << "B; ";
}
};
protected:
static std::map<std::string,ClassInfo> classes;
GlobalObjectCounter() {}
public:
static void dump(std::ostream& os) {
for (std::map<std::string,ClassInfo>::iterator i = classes.begin(); i != classes.end(); ++i) {
os << i->first << ": ";
i->second.fmt(os);
os << "\n";
}
}
};
template <class T> class ObjectCounter : public GlobalObjectCounter {
private:
static ClassInfo& classInfo() {
static ClassInfo& classInfo = classes[std::string("") + typeid(T).name()];
classInfo.size = sizeof(T);
return classInfo;
}
public:
ObjectCounter() {
classInfo().created++;
}
ObjectCounter(ObjectCounter const& oc) {
classInfo().created++;
}
ObjectCounter& operator=(const ObjectCounter&) {}
~ObjectCounter() {
classInfo().destroyed++;
}
};
The map lookup is a bit nasty, I admit it, but I didn't have the nerve to take care of storing the iterator for each class. The main issue was that you would have to explicitly initialise it for each counted class. If you know how to do that better, tell me how.
I'm not aware of gprof even attempting to deal with questions of memory usage. The obvious alternative would be valgrind
. If you only care about total memory usage, you could also do the job on your own (overload ::operator new
and ::operator delete
to track how much memory the program has requested). Of course, it's possible that you have some code that obtains memory by other means (e.g., directly calling something like sbrk
), but that's fairly unusual. Those don't attempt to track statically allocated and/or stack usage though.
Trivial.
template<typename T> class Counter {
static int count = 0;
Counter() { count++; }
Counter(const Counter&) { count++; }
Counter& operator=(const Counter&) {}
~Counter() { count--; }
};
class A : Counter<A> {
static int GetConsumedBytes() {
return sizeof(A) * count;
}
};
If the use of A involves dynamic memory, then this solution can be improved on. You can also override the global operator new/delete.
GlibC provides statistics on heap memory allocation. Take a look at mallinfo. You could probably obtain statistics at various points during execution and get some kind of idea of how much memory is being used.
精彩评论