Как профилировать потребление памяти набором классов C++?
Я пытаюсь вычислить потребление памяти моей программой (C++) с помощью gprof. Программа не имеет графического интерфейса, она полностью основана на cli.
Теперь я новичок в gprof, поэтому я прочитал несколько учебных пособий, которые научили меня, как запускать gprof и определятьВремя потребление.
Однако мне нужно выяснить потреблениепамяти определенным набором классов.
Допустим, существует программа со многими типами, A, ..., Z
. Теперь я хочу запустить свою программу и посмотреть, сколько накопилось памяти. используется объектами классов A, E, I, O, U
(например).
Я не рассматриваю исключительно gprof, я открыт для любого программного обеспечения (fos), которое выполняет эту работу.
Я, конечно, искал как в google, так и в Google. stackoverflow.com для любого ответа на эту проблему, но либо я использую неправильные ключевые слова, либо никто не имеет этой проблемы.
Edit: предложения о том, чтобы сделать это вручную, очевидны. От конечно, я мог бы закодировать его в приложение, но его о большом количестве классов я бы предпочел не менять. Кроме того, я хочу иметь общее потребление памяти, поэтому я не могу считать только все созданные объекты, потому что мне придется отслеживать размер объекта по отдельности.
Edit2: я пошел с модификацией предложенияDeadMG , которое я только должен унаследовать. Это работает довольно хорошо, так что, если у кого - то есть подобная проблема, попробуйте это.
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++;
}
};
Поиск Карты - это немного неприятно, я признаю это, но у меня не хватило смелости позаботиться о хранении итератора для каждого класса. Основная проблема заключалась в том, что вы должны были бы явно инициализировать его для каждого подсчитанного класса. Если вы знаете, как это сделать лучше, скажите мне, как.
3 ответа:
Тривиально.
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; } };
Если использование A включает динамическую память,то это решение может быть улучшено. Можно также переопределить глобальный оператор new / delete.
Я не знаю, что gprof даже пытается решать вопросы использования памяти. Очевидной альтернативой было бы
valgrind
. Если вы заботитесь только об общем использовании памяти, вы также можете выполнить эту работу самостоятельно (перегрузка::operator new
и::operator delete
для отслеживания объема памяти, запрошенного программой). Конечно, Возможно , что у вас есть некоторый код, который получает память другими средствами (например, непосредственно вызывая что-то вродеsbrk
), но это довольно необычно. Те не пытаются это сделать. однако отслеживать статически распределенное и / или использование стека.
GlibC предоставляет статистику по выделению памяти кучи. Взгляните на mallinfo. Вероятно, вы могли бы получить статистику в различных точках во время выполнения и получить некоторое представление о том, сколько памяти используется.