Bevor Sie diesen Blog lesen, empfehle ich Ihnen dringend, zunächst diese Einführung in den Client-Status zu lesen: Die Staatskunst Teil 1.
In Teil 2 werden wir uns eingehend mit der Funktionsweise der Objektverwaltung im Client-Status befassen. Wir werden uns mit hochabstrakten Konzepten befassen, daher empfehle ich Ihnen, beim Lesen ein warmes Getränk und Snacks für Ihr Gehirn bereitzuhalten (für aufregende Objektverwaltungsideen knabbere ich selbst lieber Chips).
1. Was ist Garbage Collection und warum wird sie benötigt?
Beim Modellieren Ihrer Anwendung erstellen Sie Objekte, führen Commit-, Rollback- und Löschvorgänge durch. Sie können solche Objekte in der Benutzeroberfläche anzeigen, sie an Mikro- und Nanoflows weitergeben, sie ändern oder in benutzerdefinierten Widgets mit ihnen arbeiten. Einige der Objekte, mit denen Sie arbeiten, sind persistent, andere nicht. Nicht persistente Objekte befinden sich immer im Speicher und werden daher nie in der Datenbank gespeichert. Sie können auch nie ein neues persistentes Objekt committen – das würde es effektiv nicht persistent machen, da es im Speicher vorhanden ist.
Während einer typischen Benutzersitzung arbeitet ein Benutzer stundenlang mit einer Anwendung und besucht Dutzende von Seiten. Dabei werden mehrere Objekte (persistent oder nicht persistent) erstellt. Diese Objekte werden Teil des Clientstatus und belegen Speicherplatz im Speicher des Browsers, was Ihre App mit der Zeit verlangsamen kann. Als Mendix Entwickler, Sie müssen nicht jedes Objekt entfernen, das Sie erstellen, aber nicht in der Anwendung committen, und Ihre App wird weiterhin funktionieren, ohne dass die Leistung nachlässt. Wie ist das möglich? Was bedeutet Mendix Was tun mit einem nicht persistenten Objekt, das ein Benutzer vor zehn Seiten erstellt hat? Was ist mit einer Änderung, die an einem persistenten Objekt vorgenommen wurde?
Die Antwort auf diese Fragen ist der Garbage Collection-Mechanismus.

Der Mendix Der Client analysiert Objekte und Änderungen in seinem Zustand und entfernt sie, wenn er feststellt, dass sie nicht mehr erforderlich sind. Das Ziel dieses Prozesses besteht darin, den Zustandsspeicher im Speicher zu minimieren. Herauszufinden, ob ein Mendix Welches Objekt eine App benötigt, hängt von einigen Kriterien ab, die ich weiter unten ausführlich beschrieben habe.
2. Wann erfolgt die Speicherbereinigung?
In meiner Gegend ist es normalerweise Dienstagmorgen. Für eine Mendix app, Garbage Collection läuft im Hintergrund, während Sie die App verwenden. Sie greift regelmäßig ein, analysiert alle Objekte und ihre Statusänderungen und entfernt Objekte oder Änderungen, die sie als nicht mehr notwendig erkennt.
3. Kann ich die Garbage Collection sehen?
Sie können die Verknüpfung zur Statusprüfung (Strg + Alt + G), um den Client-Status zu überprüfen und möglicherweise die Garbage Collection zu sehen. Sie brauchen jedoch ein wenig Glück, um die Objekte zu sehen, die gerade gesammelt werden. Häufig wird die Sammlung durchgeführt, bevor Sie sie sehen können. Hier können Sie ein Objekt sehen, das gesammelt wird, da die Garbage Collection noch nicht begonnen hat:

In nur wenigen Sekunden wird dieses Objekt nicht mehr sichtbar sein.
Sie können auch eine spezielle Einstellung aktivieren, um zu sehen, welche Objekte bei Garbage Collections entfernt werden. Fügen Sie dazu eine neue frustrierten Abschnitt mit dem logCleanupStatistics: trueEigentum an der dojoConfig Objekt, das in Ihrer Anwendung konfiguriert ist Thema/index.html Datei. Ihr Code sollte folgendermaßen aussehen:
dojoConfig = {
baseUrl: "mxclientsystem/dojo/",
cacheBust: "{{cachebust}}",
rtlRedirect: "index-rtl.html",
data: {
"logCleanupStatistics": true
}
};
Nach dem Hinzufügen dieses Abschnitts wird bei jeder Speicherbereinigung eine Informationsmeldung hinzugefügt:

Haftungsausschluss: Die oben genannte Konfiguration ist nicht öffentlich und kann ohne Vorankündigung geändert oder entfernt werden.
4. Wie funktioniert die Garbage Collection?
Jetzt wissen Sie, dass unnötige Objekte und Änderungen, die in der Anwendung erstellt oder geladen werden, aus dem Client-Status entfernt werden, sodass Ihre Anwendungen weiterhin schnell ausgeführt werden können. Aber wie funktioniert das?
Die konzeptionelle Antwort auf diese Frage ist einfach: die Mendix Der Client sollte wissen, ob ein Objekt zu einem bestimmten Zeitpunkt von einer Komponente benötigt wird. Wenn nicht, kann er es aus dem Status entfernen. Und da ein Mendix Objekt kann über Assoziationen auf ein oder mehrere Objekte verweisen (oder referenziert werden), die Mendix Der Client muss auch die abhängigen Objekte im Auge behalten.
Lassen Sie uns genauer untersuchen, wie diese Konzepte tatsächlich funktionieren. Mendix Kunden.
5. Abonnements
Abonnements sind der Schlüssel zur Müllabfuhr. Das Abonnementsystem ist ein Untersystem des Mendix Client, und mit ihm können Sie Benachrichtigungen anfordern, wenn Änderungen an einem Mendix Objekt oder seine Attribute. Es sieht aus wie eine einfache API für benutzerdefinierte Widgets, aber in Wirklichkeit ist die Mendix Der Kunde verwendet Abonnements häufig intern. Hier sind einige Beispiele für die interne Verwendung:
- Wenn eine Datenansicht ein Objekt lädt, abonniert sie das geladene Objekt, damit sie Benachrichtigungen zu bestimmten Situationen erhalten kann (beispielsweise wenn ein Objekt gelöscht wird).
- Die meisten Eingabe-Widgets sind auf Abonnements angewiesen, um Updates über die Objekte zu erhalten, mit denen sie arbeiten. Auf diese Weise können sie ihre Werte aktualisieren, wenn sie woanders geändert werden. Dojo-Widgets abonnieren ihre Objekte oft manuell. steckbare Widgets müssen dies nicht tun, da ihre Abonnements von der Mendix Kunden.
- Der Mendix Der Client abonniert Objekte für bedingte Sichtbarkeits- und Editierbarkeitsregeln auf der Seite, sodass er die Bedingungen neu auswertet, wenn sich das relevante Objekt oder Attribut ändert.
- Text-Widgets mit Parametern abonnieren ihre Objekte. Text-Widgets abonnieren auch alle Zwischenobjekte, wenn ein Vorlagenwert über Assoziationen hinausgeht, sodass die Widgets wissen, dass sie aktualisiert werden sollten, wenn sich Assoziationen ändern.
Abonnements werden vom Garbage-Collection-Mechanismus als Eingaben behandelt, um zu kennzeichnen, dass ein abonniertes Objekt in der App benötigt wird und nicht eingesammelt werden sollte – eine Komponente oder ein Widget verwendet oder benötigt es noch.
Der Mendix Der Client abonniert auch Objekte, die zu einem bestimmten Zeitpunkt nicht in der Benutzeroberfläche angezeigt werden, selbst ohne Verwendung des Benachrichtigungs-Callbacks. Auf diese Weise können Sie angeben, dass Mendix Der Client benötigt diese Objekte. Hier sind einige Beispiele für ein solches Verhalten:
-
Objekte, die darstellen $aktuellerBenutzer und $aktuelleSitzung sind immer abonniert innerhalb der Mendix Client, da sie so lange bestehen, wie Benutzer die App verwenden, und von der Anwendung jederzeit benötigt werden können.
Kein Tee $aktuelleSitzung Objekt wird aus Sicherheitsgründen nie an den Client zurückgesendet, aber das Mendix Der Client abonniert es immer noch. Der Grund dafür wird weiter unten erläutert.
-
Ein Datenquellen-Mikroflow für ein Datenraster kann mehr Objekte zurückgeben, als das Datenraster auf einer einzelnen Seite anzeigen kann. Diese Objekte werden Teil des Clientstatus. Der Mendix Der Client abonniert alle diese Objekte, sodass sie durch die Garbage Collection nicht versehentlich aus dem Client-Status entfernt werden.
-
Wenn eine Seite mit einem Parameter geschlossen wird, kann die Garbage Collection das Parameterobjekt aus dem Clientstatus entfernen (vorausgesetzt, das Objekt ist nicht mehr erforderlich). Ein solcher Seitenparameter kann ein nicht persistentes Objekt sein, was bedeutet, dass er durch das Entfernen für immer unzugänglich wird. Da ein Benutzer jedoch mit der Zurück-Schaltfläche des Browsers zurückkehren kann, müssen Parameterobjekte im Status beibehalten werden. Aus diesem Grund Mendix Der Client abonniert die Seitenparameterobjekte der letzten fünf Seiten: Die Garbage Collection entfernt sie daher nicht.
5.1 Kann ich sehen, warum ein Objekt in diesem Zustand gehalten wird?
Manchmal können Sie sehen, warum ein bestimmtes Objekt in diesem Zustand bleibt, indem Sie den Strg + Alt + G Verknüpfung. Im folgenden Beispiel wird die Künstler Objekt wird von Widgets auf der aktuellen Seite abonniert. Manchmal sieht man null Einträge in der Abonnierte Widgets Array. Das bedeutet, dass sie entweder vom Mendix Client intern oder von einem benutzerdefinierten Widget aus:

Daher ist es klar, dass abonnierte Objekte in diesem Zustand verbleiben sollten, solange sie abonniert sind.
Ist das alles?
6. Die Bedeutung der Erreichbarkeit
Wie bereits erwähnt, reicht es nicht aus, nur abonnierte Objekte zu behalten. Mendix Der Client muss Assoziationen berücksichtigen. Hier ist eine nicht persistente Mendix Objekt aufgerufen Objekt A innerhalb des Clientstatus:

Da es nicht abonniert ist, kann dieses Objekt bei der Garbage Collection aus dem Status entfernt werden.
Fügen wir ein weiteres Objekt hinzu — ein nicht persistentes Objekt namens Objekt B:

Beide Objekte können aus dem Client-Status entfernt werden, da keines von ihnen abonniert wurde.
Stellen Sie sich nun vor, Objekt A hat eine Verbindung und bezieht sich auf Objekt B als Wert:

Diese Situation ändert nichts. Beide Objekte können aus dem Client-Status entfernt werden, da keines von ihnen abonniert ist.
Hier Objekt A abonniert wird über den mx.data.subscribe API (beachten Sie das rote Leuchten um Objekt A):

In dieser Situation sollten beide Objekte im Status verbleiben. Warum?
Objekt A ist abonniert und sollte daher nicht gesammelt werden, da der Garbage Collection-Mechanismus abonnierte Objekte nicht entfernt.
Objekt B ist nicht abonniert, aber das bedeutet nicht, dass es gesammelt werden kann, weil Objekt A bezieht sich darauf. Betrachten Sie einen Mikrofluss, der akzeptiert Objekt A als Parameter. Innerhalb dieses Mikroflusses Objekt B wird abgerufen mit einem Aktivität abrufen mit dem Association Retrieve-Typ. Wenn Garbage Collection entfernt Objekt B aus dem Status, dieser Mikrofluss wäre nicht in der Lage, es abzurufen.
Daher sollte die Garbage Collection dies ebenfalls berücksichtigen und Objekt B im Client-Status. Dies sollte aus folgendem Grund geschehen:
- Objekt B ist „erreichbar“ von Objekt A: Sie sind verbunden. Eine Abrufaktivität in einem Mikro- oder Nanoflow kann ihn erreichen über Objekt A.
- Objekt B ist nicht persistent, d. h. es kann nicht durch die Abrufaktivität in einem Mikroflow aus der Datenbank geladen werden. Wenn es sich um eine persistente Entität handeln würde (die festgeschrieben ist), könnte ein Mikroflow sie aus der Anwendungsdatenbank abrufen.
Fügen wir der Mischung ein neues Objekt hinzu. Was soll passieren mit Objekt C. wann erfolgt die Speicherbereinigung?

Objekt C. sollte auch im Staat gehalten werden, weil es erreicht werden kann durch Objekt A -> Objekt B -> Objekt C.
Möglich ist das auch Objekt A kann auf zwei verschiedene Objekte als Wert derselben Assoziation verweisen. Wie kann das passieren? Stellen Sie sich vor, dass Objekt A ist mit einem Verein verbunden, der sich auf Objekt BWenn Sie denselben Assoziationspunkt anbringen, Objekt D ohne Commit führen Sie eine „Änderung“ für diese Assoziation ein. In diesem Fall Objekt A kennt sowohl den festgeschriebenen als auch den geänderten Wert für dieselbe Assoziation:

Die Garbage Collection berücksichtigt diesen Fall und behält sowohl Objekt B und Objekt C. im Staat, denn beide sind erreichbar von Objekt A.
Alle obigen Beispiele betreffen nicht persistente Objekte. Lassen Sie uns persistente Objekte hinzufügen. Sie werden durch den hellblauen Hintergrund dargestellt:

Lassen Sie uns durchgehen, was mit jedem persistenten Objekt bei der Garbage Collection geschehen soll.
Objekt B sollten aus folgenden Gründen nicht erhoben werden:
- Der (Neu) Das Suffix am Ende des Namens zeigt an, dass es noch nicht festgeschrieben wurde, wodurch sich das Objekt effektiv wie ein nicht persistentes Objekt verhält. Es kann nur im Speicher gefunden werden.
- Es wurde referenziert von Objekt Aund markiert es als „erreichbar“. Wäre es nicht referenziert worden, hätte die Garbage Collection es aus dem Client-Status entfernen können.
Objekt C. sollten aus folgenden Gründen nicht erhoben werden:
- Der
**am Ende des Namens zeigt an, dass es nicht festgeschriebene Attribut-/Assoziationsänderungen gibt. Solche Änderungen bleiben nur so lange im Speicher, bis Objekt C. wird entweder festgeschrieben oder zurückgesetzt. - Es wurde referenziert von Objekt Aund markiert es als „erreichbar“. Wäre es nicht referenziert worden, hätte die Garbage Collection es aus dem Client-Status entfernen können.
Objekt D können aus folgenden Gründen erhoben werden:
- Es handelt sich um ein festgeschriebenes Objekt (es gibt kein (Neu) Suffix).
- Es enthält auch keine Änderungen (keine
**nach seinem Namen).
Dies bedeutet, dass Objekt D enthält keine nicht festgeschriebenen Attributwerte und kann bei Bedarf in der Datenbank der App gefunden werden. Der Garbage Collection-Mechanismus entfernt es daher aus dem Clientstatus, selbst wenn darauf verwiesen wird von Objekt A.
Objekt E kann gesammelt werden, da es von keinem abonnierten Objekt referenziert wird. Das bedeutet, dass es überhaupt nicht zugänglich ist. Die Garbage Collection kann dieses Objekt aus dem Clientstatus entfernen, einschließlich der nicht festgeschriebenen Attribut-/Assoziationsänderungen. Da dieses Objekt nicht mehr erreichbar ist, kann es sicher entfernt werden.
Im vorigen Abschnitt haben wir erwähnt, dass $aktuelleSitzung (System.Session) ist immer abonniert im Mendix Client, aber er landet nie im Zustand. Nun können Sie den Grund erraten: Es könnten Objekte im Zustand sein, die auf den $aktuelleSitzung, also von dort aus „erreichbar“. Deshalb könnten sie auch im Staat gehalten werden.
7. Fazit
Mit der obigen Beschreibung können wir den Garbage Collection-Prozess wie folgt zusammenfassen:
Die Garbage Collection beginnt mit allen abonnierten Objekten im Status und findet alle „erreichbaren“ Objekte über Assoziationen von ihnen, indem ein Abhängigkeitsdiagramm erstellt wird. Durch die Analyse dieses Diagramms wird entschieden, ob jedes Objekt und (falls vorhanden) seine Änderungen im Clientstatus beibehalten oder verworfen werden.
7.1 Welche Objekte werden im Staat aufbewahrt?
- Alle abonnierten Objekte bleiben im Status.
- Alle von abonnierten Objekten „erreichbaren“ Objekte werden beibehalten, wenn sie in eine dieser Kategorien fallen:
- Nicht persistente Objekte, da sie nicht in der Datenbank gefunden werden können.
- Permanente Objekte, die erstellt, aber noch nicht festgeschrieben wurden, da sie sich noch nicht in der Datenbank der App befinden.
- Persistente Objekte, die festgeschrieben sind, aber Änderungen enthalten, weil die Änderungen noch nicht in der Datenbank vorhanden sind – ein Mikrofluss sie aber möglicherweise benötigt.
7.2 Welche Objekte werden aus dem Staat entfernt?
- Objekte, die von abonnierten Objekten aus nicht erreichbar sind, werden verworfen. Solche Objekte stammen häufig von vorherigen Seiten, die der Benutzer besucht hat.
- Objekte, die noch von abonnierten Objekten aus erreichbar sind, deren Status jedoch mit dem der Datenbank übereinstimmt, werden verworfen. Dieser Fall trifft auf persistente Objekte zu, wenn sie in die Datenbank übernommen wurden und keine Änderungen aufweisen. Wenn die Objekte benötigt werden, können sie aus der Datenbank geladen werden.
Nach dem Lesen der obigen Beschreibungen fühlen Sie sich möglicherweise etwas katatonisch:

So, genug mit den Beschreibungen. Lasst uns das Gelernte in die Praxis umsetzen!
8. Das Müllabfuhrspiel
Vorher habe ich den Garbage Collection-Mechanismus anhand von Grafiken erklärt. Jetzt können Sie ein Spiel spielen, um zu sehen, ob Sie den Mechanismus verstehen. Die Szenarien des Spiels stammen aus unseren internen Unit-Tests für den GC-Mechanismus. Mal sehen, ob Sie die richtigen Antworten erraten können!
Das Spiel ist einfach. Unten sehen Sie eine Darstellung des Clientstatus und die Legende ist dieselbe wie oben. Hier ist ein Beispiel:

Durch die Grafik können Sie folgende Dinge über Objekt 1:
- Es handelt sich um eine persistente Entität (blauer Hintergrund)
- Es ist abonniert (das rote Leuchten darum herum)
- Es ist noch nicht in der Datenbank enthalten (hat „(neu)“ am Ende seines Namens)
- Es enthält Änderungen. (hat
**am Ende seines Namens)
Nach diesem Fall haben Sie vielleicht eine Frage: Kann ein „neues“ Objekt Änderungen aufweisen? Das ist möglich, denn wenn ein Objekt erstellt wird, behalten seine Attribute ihren „Standardwert“, der im Domänenmodell definiert werden kann. Diese Standardwerte werden zum aktuellen „festgeschriebenen“ Wert der Attribute und alle an ihnen vorgenommenen Änderungen werden im Status gespeichert.
Objekte können sich auch über Assoziationen gegenseitig referenzieren:

Oben sehen Sie, dass Objekt 1 hat eine Assoziation mit einem Wert, der auf Objekt 2. Weder der Name noch die Kardinalität der Assoziation sind für dieses Spiel von Bedeutung, daher werden sie nicht angegeben. Dieser Pfeil besagt, dass Objekt 2 Der Zugriff erfolgt über eine Aktivität abrufen in einem Mikrofluss mit dem Verein Abruftyp.
Das Spiel besteht aus sieben Leveln. Jedes Level stellt den aktuellen Zustand des „Client-Status“ vor der Garbage Collection dar. Ihr Ziel ist es, zu bestimmen, welche Objekte im Status beibehalten und welche Objekte aus dem Status entfernt werden, wenn die Garbage Collection stattfindet. Danach können Sie auf „Antworten anzeigen“ klicken, um die Ergebnisse anzuzeigen. Dann können Sie zum nächsten Level übergehen.
Lasst das Spiel beginnen!
Ich hoffe, das Spiel hat euch gefallen! Jetzt, da ihr wisst, wie Mendix Der Client bereinigt den Status. Hier sind einige Hinweise zum Modellieren besserer Apps unter Berücksichtigung der Speicherbereinigung.
9. Best Practices: Beim Modellieren die Garbage Collection berücksichtigen
9.1 Nicht zu viele Objekte aus Datenquellen zurückgeben
Stellen Sie sich eine Listenansicht mit einer Microflow-Quelle vor, die Tausende von Objekten zurückgibt. Alle diese Objekte bleiben im Status, während eine Listenansicht je nach Seitenkonfiguration nur einen kleinen Teil davon zu einem bestimmten Zeitpunkt anzeigen kann. Dies gilt auch für eine Nanoflow-Datenquelle und eine Assoziationsdatenquelle. Versuchen Sie stattdessen, XPath oder eine Datenbankdatenquelle zu verwenden, die für große Datensätze optimiert ist. Sie lädt nur die Daten, die auf der aktuellen Seite angezeigt werden können.
9.2 Große Einheiten in kleinere aufteilen
Das Arbeiten mit großen Objekten vergrößert den Zustand Ihrer App. Ein ganzes großes Objekt wird im Speicher gespeichert, auch wenn es nur eine einzige Änderung aufweist oder nur für eines seiner Attribute abonniert ist. Das Aufteilen solcher Objekte kann für die Garbage Collection von Vorteil sein, insbesondere bei nicht persistenten Objekten. Auf diese Weise kann der Garbage Collection-Algorithmus nicht verwendete kleinere Objekte entfernen, wenn sie die oben genannten Bedingungen erfüllen.
9.3 Keine „Sternobjekte“ erstellen
Ein „Sternobjekt“ ist ein Objekt, auf das von Hunderten anderer Objekte verwiesen wird. Wenn Sie beispielsweise ein Suchergebnis Objekt, und es gibt 500 SuchergebnisElement Bezugnehmend darauf, Suchergebnis wird zum Star-Objekt. Wenn es Abonnements für eines der beiden gibt Suchergebnis Oder irgendwelche der SuchergebnisElement Objekte, können alle Objekte im Status verbleiben. Dieses Muster ist häufig problematisch, wenn alle Objekte nicht persistent sind oder Änderungen enthalten.
Wenn Sie mit solchen Objekten arbeiten müssen, achten Sie darauf, dass Sie diese manuell festschreiben oder löschen oder die Werte der Assoziationen zu einem Sternobjekt auf leer nachdem Sie sie verwendet haben.
9.4 Überprüfen Sie die Größe des Staates während der Entwicklung
Verwenden Sie die Strg + Alt + G Verknüpfung, um die Größe des Status zu überprüfen. Das Überprüfen des Inhalts des Status ist besonders wichtig, wenn Sie mit großen Seiten arbeiten. Beispielsweise können Sie feststellen, dass ein Objekt dort verbleibt, weil Sie vergessen haben, es in Ihrem benutzerdefinierten Widget zu kündigen.
9.5 Laufzeitprotokolle auf übermäßigen Zustand prüfen
Der Mendix Der Client sendet erforderliche Teile des Status an Laufzeitanforderungen und es wird eine Warnung protokolliert, wenn die Anzahl der vom Client gesendeten Objekte einen bestimmten Schwellenwert überschreitet. Wenn Sie eine solche Warnung sehen, sollten Sie diese Seite erneut aufrufen und untersuchen, warum so viele Objekte im Status gespeichert sind.
Ich hoffe, dass Ihnen der Beitrag gefallen hat und dass er hilfreich ist. Wenn Sie Anmerkungen, Fragen oder allgemeines Lob haben 😉, kontaktieren Sie mich bitte. werden auf dieser Seite erläutert.