2016-09-15 39 views
-1

根據以下示例中的隱式共享概念,我們必須在Windows任務管理器中體驗低內存使用情況。Qt中的隱式共享概念令人困惑

我們在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使用
  • 調試:1.89億RAM使用

問:

基於提供環路承擔EmployeeData大小12字節,它必須創造EmployeeData一個實例,分享另有999,999個對象實例,因此內存使用量必須至少減少到3M以下,是不是?

因此,如果我們取消註釋以下行,它必須創建1000,000個唯一的實例EmployeeData,因此實例使用的內存增加了,是嗎?

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

只有一個Employee對象(複製普通指針就是這樣,複製普通指針)創建,然後進行修改以及泄漏的每循環迭代。您的代碼不會以任何方式利用共享數據。用QString替換Employee,然後思考它將如何工作。您需要將Employee變量用作值,而不是指針。 – hyde

+0

@hyde我用'QString'替換'Employee',所以在釋放模式下,如果我們假設QString共享'1KB'的數據,那麼我有'16M'的RAM使用,所以可能會有另一個額外的非共享數據空間,我的問題都是關於共享數據,QString可能有許多數據成員在每個實例中不共享,但在EmployeeData中我們有兩個數據成員,因此只有一個實例必須在另一個對象之間共享。 –

+0

但就是這樣,你沒有多個實例共享任何地方的數據。要做到這一點,你需要這樣的東西:Employee e2 = * e1; – hyde

回答

2

這裏沒有隱式共享,只有2個指針指向同一個對象。

隱式共享僅在使用對象的複製構造函數或賦值運算符時纔有效。

忽略new的嚴重的內存泄露的for循環,這樣做將利用隱含共享

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