根據以下示例中的隱式共享概念,我們必須在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
副本。
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使用
- 調試:1.89億RAM使用
問:
基於提供環路承擔EmployeeData
大小12
字節,它必須創造EmployeeData
一個實例,分享另有999,999個對象實例,因此內存使用量必須至少減少到3M以下,是不是?
因此,如果我們取消註釋以下行,它必須創建1000,000個唯一的實例EmployeeData
,因此實例使用的內存增加了,是嗎?
//e1->setName("Hans Holbein");
只有一個Employee對象(複製普通指針就是這樣,複製普通指針)創建,然後進行修改以及泄漏的每循環迭代。您的代碼不會以任何方式利用共享數據。用QString替換Employee,然後思考它將如何工作。您需要將Employee變量用作值,而不是指針。 – hyde
@hyde我用'QString'替換'Employee',所以在釋放模式下,如果我們假設QString共享'1KB'的數據,那麼我有'16M'的RAM使用,所以可能會有另一個額外的非共享數據空間,我的問題都是關於共享數據,QString可能有許多數據成員在每個實例中不共享,但在EmployeeData中我們有兩個數據成員,因此只有一個實例必須在另一個對象之間共享。 –
但就是這樣,你沒有多個實例共享任何地方的數據。要做到這一點,你需要這樣的東西:Employee e2 = * e1; – hyde