В соответствии с концепцией неявного совместного использования в следующем примере мы должны испытывать низкое использование памяти в диспетчере задач 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
Результат (из диспетчера задач):
Вопрос:
На основании предоставленного цикла предположим EmployeeData
размер как 12
байты, он должен создать один экземпляр EmployeeData
и поделиться им с другими 999 999 экземплярами объекта, и, таким образом, использование памяти должно быть уменьшено как минимум до 3M, это нормально?
Поэтому, если мы раскомментируем следующую строку, она должна создать 1000 000 уникальных экземпляров EmployeeData
Так память, используемая экземплярами, увеличивается, это нормально?
//e1->setName("Hans Holbein");
Здесь не происходит неявное совместное использование, просто у вас есть 2 указателя на один и тот же объект.
Неявное совместное использование работает только при использовании конструктора копирования или оператора присваивания объекта.
Игнорирование огромной утечки памяти new
в цикле for при этом будет использоваться неявный обмен
Employee *e2 = new Employee(e1); // copy constructor, implicit sharing
Других решений пока нет …