2016-09-15 3 views
-1

В соответствии с концепцией неявного совместного использования в следующем примере мы должны испытывать низкое использование памяти в диспетчере задач Windows.Путаница о неявной концепции совместного использования в Qt

Мы создаем объект 1000000 в цикле for из класса Employee и можем совместно использовать его внутренние данные (EmployeeData класс) между созданными объектами.

for (int i = 0; i < 1000000; ++i) { 

    Employee *e1 = new Employee(); // calls default constructor 
    Employee *e2 = e1; 
    Employee *e3 = e2; 

    //e1->setName("Hans Holbein"); // *** 
} 

***: если раскомментировать упоминается линия согласно Qt документации QSharedDataPointer будет отсоединяется от общих данных и создает свою собственную копию EmployeeData.

EmployeeData и Employee класс:

class EmployeeData : public QSharedData 
{ 
    public: 
    EmployeeData() : id(-1) { } 
    EmployeeData(const EmployeeData &other) 
     : QSharedData(other), id(other.id), name(other.name) { } 
    ~EmployeeData() { } 

    int id; 
    QString name; 
}; 

class Employee 
{ 
    public: 
    Employee() { d = new EmployeeData; } 
    Employee(int id, const QString &name) { 
     d = new EmployeeData; 
     setId(id); 
     setName(name); 
    } 
    Employee(const Employee &other) 
      : d (other.d) 
    { 
    } 
    void setId(int id) { d->id = id; } 
    void setName(const QString &name) { d->name = name; } 

    int id() const { return d->id; } 
    QString name() const { return d->name; } 

    private: 
    QSharedDataPointer<EmployeeData> d; 
}; 

Платформа: Windows 10

Qt Версия: 5.7

Компилятор: MSVC 2015 32bit

Результат (из диспетчера задач):

  • выпуска: 40M использование RAM
  • Debug: использование RAM 189M

Вопрос:

На основании предоставленной петли предположить EmployeeData размер как 12 байт, он должен создать один экземпляр EmployeeData и поделиться с еще 999999 объектами, и поэтому использование памяти должно быть уменьшено, по крайней мере, до 3M, так ли?

Итак, если мы раскомментируем следующую строку, он должен создать 1000 000 уникальных экземпляров EmployeeData, поэтому память, используемая экземплярами, увеличивается, это так?

//e1->setName("Hans Holbein"); 
+0

Там только один объект Employee (копирование простых указателей только что, копируя простые указатели), созданный и затем модифицированное и пропущенную итерационную петлю. Ваш код не использует преимущества общих данных. Замените Employee QString и подумайте, как это будет работать. Вы должны использовать переменные Employee в качестве значений, а не как указатели. – hyde

+0

@hyde Я заменил 'Employee'' QString', поэтому в режиме освобождения я использую использование 16M' RAM, если мы предположим, что данные QString об «1KB», так что может быть еще одно дополнительное пространство без совместного использования, мой вопрос все об общих данных, QString может иметь много членов данных, которые не разделяются в каждом экземпляре, но в «EmployeeData» у нас есть два элемента данных, поэтому только один экземпляр должен быть разделен между другими объектами. –

+0

Но это именно так, у вас нет нескольких экземпляров с общими данными в любом месте.Для этого вам понадобится что-то вроде: Employee e2 = * e1; – hyde

ответ

2

Здесь не подразумевается совместное использование, у вас есть только 2 указателя на один и тот же объект.

Неявное совместное использование работает только при использовании конструктора копирования или оператора присваивания объекта.

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

Employee *e2 = new Employee(e1); // copy constructor, implicit sharing