Смущает концепция неявного совместного использования в Qt

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

Мы создаем 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

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

  • Релиз: 40 МБ оперативной памяти
  • Отладка: 189 МБ ОЗУ

Вопрос:

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

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

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

-1

Решение

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

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

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

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]