Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как узнать сколько памяти занимает объект?


Автор: Elfet 24.3.2010, 13:01
Приветствую! 

Есть у меня достаточно большой класс сетки. Можно ли как-нибудь узнать сколько памяти занимает экземпляр этой сетки?

Заранее спасибо! 

Автор: GoldFinch 24.3.2010, 13:12
sizeof, или подсчитывай сколько выделяешь в new

Автор: RatHat 24.3.2010, 13:13
"Сколько занимает Виндовс? Сколько находит, столько и занимает!"

А по теме...интересно было бы посмотреть на класс сначала.

Автор: Elfet 24.3.2010, 13:17
Вот класс:

Сетка:
Код

#ifndef MESH_H
#define MESH_H
#include "main.h"
#include "Node.h"
#include "Edge.h"
#include "Element.h"
#include "Physical.h"

namespace Dimension
{
    enum Dimension
    {
        Dim2 = 2,
        Dim3 = 3,
    };
}

class Element;
class Mesh
{
public:
    Mesh(void);
    ~Mesh(void);
    void Init();
    void Clear();
    void AddNode(Node * node);
    void AddElement(Element * elem);
    void AddEdge(Edge * edge);
    void RestoreAdjacentElements();
    Node * GetNodeByIndex(int index);
    Element * GetElementByIndex(int index);
    int GetNodesCount();
    void SetMaximumDistances(float _max_x, float _min_x, float _max_y, float _min_y);
    void SetMaximumDistances(float _max_x, float _min_x, float _max_y, float _min_y,float _max_z, float _min_z);
    void BuildApproximation(short order);
    void Verification(short funcIdentifier);
    void Reorder();
    void AfterLoad(); // Выполняет подсчёт центров, дельт, и проч.
public:
    static Dimension::Dimension Dim;
    vector<Element*> *elements;
    vector<Node*> *nodes;
    vector<Edge*> *edges;

    Element * selectedElement; // Ссылка на выбранный элемент в этой сетке.

    float max_x, min_x, max_y, min_y, max_z, min_z; // param for "good" drawing

    Physical maximumValueOfVariable;
    Physical minimumValueOfVariable;

    bool flagVerified;
    bool flagLoaded; 
    double sumResidual;
    bool flagApproximated; // Approximat is done?

private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & Dim;
        ar & nodes;
        ar & edges;
        ar & elements;

        ar & max_x;
        ar & min_x;
        ar & max_y;
        ar & min_y;
        ar & max_z;
        ar & min_z;
    }

};

BOOST_CLASS_VERSION(Mesh, 1);

typedef boost::shared_ptr<Mesh> shared_mesh_ptr;
typedef boost::weak_ptr<Mesh> weak_mesh_ptr;

#endif



Элемент:
Код

#ifndef ELEMENT_H
#define ELEMENT_H
#include "main.h"
#include "Mesh.h"
#include "Approximation.h"
#include "Physical.h"

class Approximation;
class Element;

struct WeightElement; // Структура для хранения в списке окружения ссылки элемента и его относительного веса.
struct DistToEdge;

class Element
{
public:
    Element(void);
    Element(int _index);
    Element(int _index, vector<Node*> *_nodes);
    ~Element(void);

    void    CalculateCenter();
    void    CollectSurrounding(int);
    void    CalculateDistToEdge();
    void    Reorder();
    void    CalculateLimitingFactors(const row&);        // вычисляет значение ограничивающего множителя
    int     CalculateApproxCoef(short order);            // строит аппроксимацию заданнного порядка

    // вычисляет значение переменной и её производных в серединах граней по значениям переменной в соседних ячейках
    void    CalculateVarValues();
    // спец. версия предыдущей функции, используемая в функции верификации
    void    CalculateVarValuesVerification(const row& q);
    // вычисляет значение переменной в середине i-й грани по значениям переменной в соседних ячейках
    double  CalculateVarValue(const row& q, int i, double limitingFactor = 1);

    void    IntegrateQuadResidual(short funcIdentifier, const row& q);

    double  getCenterX();
    double  getCenterY();
    double  getCenterZ();

    row*    getEdgeValues(int varNumber);
    matrix* getEdgeCenters();

public:

    int                  index;
    vector<Node*>       *baseNodes;
    vector<Edge*>       *baseEdges;
    vector<Element*>    *adjacentElements;
    vector<int>         *adjacentElementIndexes; // Нужно только для востановления соседей после сериализации
    vector<int>          edgeOrientation;
    list<WeightElement> *surroundingElements;
    vector<DistToEdge>  *distToEdges;

    list<Physical>            vars;    // Значения переменных решения в центре ячейки на шагах n-1,n,n+1
    Physical                  limitingFactors;    // Ограничивающие множители
    vector<Physical>          edgeValues;         // Значения аппроксимации на гранях (БЕЗ ограничивающего множителя)
    vector<Physical>          edgeValuesLimited;  // Значения аппроксимации на гранях (С ограничивающим множителем)
    vector<vector<Physical> > edgeDerivativeValuesX; // Значения производных по x
    vector<vector<Physical> > edgeDerivativeValuesY; // Значения производных по y
    vector<vector<Physical> > edgeDerivativeValuesZ; // Значения производных по z

    Approximation       *approximation;

    row                  varValues;       // значения аппроксимации 0-в центре элемента - далее в центрах граней
    row                  funValues;       // значения аппроксимируемой функции в центрах граней
    double               residual;     // среднеквадратическая погрешность, проинтегрированная по элементу


private:
    double center_x, center_y, center_z;
private:
    double CalculateSquaredDistances(Element * toElement);
    void   CalculateDeltaXYZDistances(Element * toElement, double & dx, double & dy, double & dz);
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & index;
        ar & baseNodes;
        ar & baseEdges;
        ar & adjacentElementIndexes;
    }
};


// Структура для хранения в списке окружения ссылки элемента и его относительного веса.
struct WeightElement
{
    double   dx, dy, dz;
    double   weight;
    Element *element;

    WeightElement(Element * _element, double _weight, double _dx, double _dy, double _dz)
    {
        element = _element;
        weight = _weight;
        dx = _dx;
        dy = _dy;
        dz = _dz;
    }

    bool operator<(const WeightElement &o)
    {
        return weight < o.weight;
    }
};

struct DistToEdge
{
    double xDistToEdge, yDistToEdge, zDistToEdge;

    DistToEdge(double _xDistToEdge, double _yDistToEdge, double _zDistToEdge)
    {
        xDistToEdge = _xDistToEdge;
        yDistToEdge = _yDistToEdge;
        zDistToEdge = _zDistToEdge;
    }
};

#endif


Автор: mes 24.3.2010, 13:22
Цитата(Elfet @  24.3.2010,  12:17 Найти цитируемый пост)
Вот класс:

Достаточно было привести (не статические) дата-члены, потому что остальное место "в объекте" не занимает (указатель на втабле не расматриваем smile)

Цитата(Elfet @  24.3.2010,  12:01 Найти цитируемый пост)
ь сколько памяти занимает экземпляр

разное, так как включает в себя динамические структуры... или интересует минимум ?

Автор: Elfet 24.3.2010, 13:28
нет, интересуем всё, со всеми векторами и списками. smile

Дело в том что сейчас мы используем сетки с 20-25 тыс. элементами, но планируем потом использовать сетки с миллионом элементов. И мне хочется подсчитать сколько оперативки мне понадобится. 

Автор: mes 24.3.2010, 13:36
Цитата(Elfet @  24.3.2010,  12:28 Найти цитируемый пост)
Дело в том что сейчас мы используем сетки с 20-25 тыс. элементами, но планируем потом использовать сетки с миллионом элементов. И мне хочется подсчитать сколько оперативки мне понадобится.  


на глаз размер Element`a в "минимальной комплектации" тянет более чем на килобайт.
10 пустых векторов это уже  250-500 байт в зависимости от библиотеки.

используя sizeof и зная связи можете самостоятельно сделать приблизительную более точной.
или перегрузите new, как советовал GoldFinch..

Автор: Elfet 24.3.2010, 14:00
Насчёт перегрузки new? можно по подробнее как это сделать? 

Автор: azesmcar 24.3.2010, 15:18
Цитата(Elfet @  24.3.2010,  14:00 Найти цитируемый пост)
Насчёт перегрузки new? можно по подробнее как это сделать?  

http://www.bearcave.com/software/c++_mem.html
http://www.devx.com/tips/Tip/5608

но мне не совсем понятно что это даст? каким образом будет отличаться память, выделяемая для этого класса, от памяти выделяемого для другого если учесть что

Цитата(Elfet @  24.3.2010,  13:28 Найти цитируемый пост)
интересуем всё, со всеми векторами и списками


Автор: Elfet 24.3.2010, 15:58
что-то я не понял как всё равно мне узнать скока занимает экземпляр места в памяти.

Автор: azesmcar 24.3.2010, 16:10
Elfet

Для любого вида объекта - никак, для своего частного случая можешь написать функцию в классе и суммировать (sizeof(*this) + размеры всех динамически выделенных объектов, массивов и контейнеров).

Автор: GoldFinch 24.3.2010, 16:36
Elfet, я заметил у вас код сериализации - так сериализуйте в бинарный архив, и посмотрите его размер

Автор: Elfet 24.3.2010, 17:53
azesmcar, ясно, нужно вручную считать. А нет ли какие-нибудь аппаратных средств которые это бы сделали сами? 


GoldFinch, можно было бы и так, только после загрузки сетки создаётся множество данных, которые в сереализацию не попадают.

Автор: mes 24.3.2010, 18:14
Цитата(Elfet @  24.3.2010,  16:53 Найти цитируемый пост)
только после загрузки сетки создаётся множество данных, которые в сереализацию не попадают. 

ну так приблизительно оценить можно также по кол-ву занимаемой памяти..
замерьте память при нескольких размерах сетки и на этой основе можно буде сделать приблизительную оценку.

Автор: Elfet 24.3.2010, 19:30
mes, а как её замерить? smile Я только через диспетчер умею smile

Автор: Earnest 24.3.2010, 20:27
Напиши объекту функцию CalcSize, и пусть сам считает, учитывает свой sizeof и все динамические структуры. Если в векторах не PODы - для них аналогично. Вызывай где-надо, выводи, и будешь точно знать. Делов-то.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)