2016-09-15 2 views
-1

Nach implizit Sharing-Konzept im folgenden Beispiel müssen wir geringe Speicherauslastung in Windows Task-Manager erleben.Verwirrende über implizite Freigabe-Konzept in Qt

Wir erstellen 1000000 Objekt in einer for-Schleife von Employee Klasse und es kann seine internen Daten (EmployeeData Klasse) zwischen erstellten Objekten teilen.

for (int i = 0; i < 1000000; ++i) { 

    Employee *e1 = new Employee(); // calls default constructor 
    Employee *e2 = e1; 
    Employee *e3 = e2; 

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

***: wenn uncomment erwähnte Linie Qt Dokumentation nach QSharedDataPointer es wird von gemeinsam genutzten Daten seines ablöst und erstellt seine eigene Kopie von EmployeeData.

EmployeeData und Employee Klasse:

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; 
}; 

Plattform: Windows 10

Qt Version: 5.7

Compiler: MSVC 2015 32bit

Das Ergebnis ist (mit dem Task-Manager):

  • Release: 40M RAM-Nutzung
  • Debug: 189m RAM-Nutzung

Frage:

Basierend auf bereitgestellt Schleife übernehmen EmployeeData Größe als 12 Bytes, muss es eine Instanz von EmployeeData erstellen und teilen mit weiteren 999.999 Objektinstanzen, und so muss die Speichernutzung mindestens unter 3M reduziert werden, ist es Ok?

Also, wenn wir die folgende Zeile auskommentieren müssen 1000000 eindeutige Instanz von EmployeeData erstellt werden, so Speicher von Instanzen geht nach oben, ist das Ok?

+0

gibt es nur ein Objekt Employee (plain Zeiger Kopieren ist nur, dass das Kopieren von Klar Zeiger) erstellt und dann bearbeitet und die ausgelaufene Iteration pro Schleife. Ihr Code nutzt die gemeinsamen Daten in keiner Weise. Ersetzen Sie Mitarbeiter durch QString und denken Sie darüber nach, wie es dann funktionieren würde. Sie müssen die Employee-Variablen als Werte verwenden, nicht als Zeiger. – hyde

+0

@hyde Ich habe "Employee" durch "QString" ersetzt, also im Release-Modus habe ich '16M' RAM-Nutzung, wenn wir QString freigegebene Daten über' 1KB' annehmen, könnte also noch einen weiteren nicht gemeinsamen Datenraum haben, meine Frage alle Über Shared-Data kann QString viele Datenelemente haben, die nicht in jeder Instanz gemeinsam genutzt werden, aber in 'EmployeeData' haben wir zwei Datenelemente, so dass nur eine Instanz unter anderen Objekten geteilt werden muss. –

+0

Aber das ist es nur, Sie haben nicht überall mehrere Instanzen mit geteilten Daten.Um das zu haben, brauchen Sie etwas wie: Mitarbeiter e2 = * e1; – hyde

Antwort

2

Es gibt keine implizite Freigabe hier, Sie haben nur 2 Zeiger auf das gleiche Objekt.

Die implizite Freigabe funktioniert nur, wenn der Kopierkonstruktor oder der Zuweisungsoperator des Objekts verwendet wird.

Ignorieren der großen Speicherverlust des new in der for-Schleife, dies zu tun implizite Sharing nutzen wird

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