在Qt中混淆隐含共享概念

时间:2016-09-15 16:09:59

标签: c++ qt qt5 qshareddata

根据以下示例中的隐式共享概念,我们必须在Windows任务管理器中体验到低内存使用率。

我们在Employee类的for循环中创建1000000对象,它可能在创建的对象之间共享其内部数据(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副本。

EmployeeDataEmployee类:

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使用
  • 调试:189M RAM使用

问题:

基于提供的循环假设EmployeeData大小为12字节,它必须创建一个EmployeeData实例并与另外999,999个对象实例共享,因此必须减少内存使用量至少在3M下,是吗?

因此,如果我们取消注释以下行,它必须创建1000,000个EmployeeData的唯一实例,因此实例使用的内存会增加,是吗?

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

1 个答案:

答案 0 :(得分:2)

这里没有隐式共享,只有2个指针指向同一个对象。

隐式共享仅在使用对象的复制构造函数或赋值运算符时有效。

忽略for循环中new的巨大内存泄漏,这样做会利用隐式共享

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