In Kotlin können Sie einen Singleton mithilfe eines Begleitobjekts erstellen:
class MyClass {
companion object {
fun doSomething() {
}
}
}
Laut den Kotlin-Dokumenten heißt es:
Beachten Sie, dass die Mitglieder von Begleitobjekten, obwohl sie in anderen Sprachen wie statische Elemente aussehen, zur Laufzeit immer noch Instanzmitglieder von realen Objekten sind ...
https://kotlinlang.org/docs/reference/object-declarations.html
Bedeutet dies, dass nach Verwendung einer Funktion im Begleitobjekt die Instanz der Klasse (MyClass) für den gesamten Lebenszyklus der App im Speicher verbleibt? Gibt es in Android Studio eine Möglichkeit, zu überprüfen, ob dies der Fall ist?
Antworten:
Begleitobjekt in JVM
in Kotlin
MyClass (Kotlin) wurde in JVM konvertiert
Wie oben beschrieben,
companion object
wird CodeCompanion
in JVM als Klasse deklariert und alsstatic
Feld innerhalb derMyClass
Klasse erstellt. Somit wird nicht von gc gesammelt. So bleibt die Erinnerung an das Objekt (Companion) während desProcessLifecycle
.static final object
wird im Normalfall nicht freigegeben.Wenn auf eine
MyClass.Companion
Instanz in der Anwendung verwiesen wird , wird diese Instanz nicht als Müll gesammelt. (über allgemeine Klassenlader).* Wenn
MyClass.Companion
in der Anwendung nicht auf die Instanz verwiesen wird , kann sie durch die Funktion zum Verkleinern des Codes entfernt werden .Sie können durch Android Studio> Profiler> Heap Dump sehen.
Referenz
quelle
Wie Sie zu wissen scheinen und die obige Antwort auch deutlich macht, dass Begleitobjekte in Klassen übersetzt werden und die Klasse, die sie deklariert, einen statischen Verweis auf das Objekt der Begleitklasse enthält, wie folgt:
Nun die Frage
Da die deklarierende Klasse einen
static
Verweis auf die Companion-Klasse enthält, reduziert sich die Frage auf die Lebensdauer derstatic
Felder in jvmclass
und die Antwort liegt in der JVM-Spezifikation , aber die Spezifikation ist in der Erklärung etwas trocken, sodass ich einige Ausschnitte aus dem Buch Inside hinzufüge die Java Virtual Machine .Nehmen wir an, wir haben wie in Ihrem Beispiel ein
class
Objekt mit nur einem Begleiter.Die erste Frage ist, wann ein Objekt der Companion-Klasse erstellt wird. oder wenn
static
Felder initialisiert werden?relevanter Text aus dem Buch . (Für den Kontext spricht das Buch über das Laden von Klassen)
Wir wissen also, dass nach dem
MyClass
Laden und Initialisieren das Objekt der Companion-Klasse erstellt wird.aber was würde dazu führen, dass JVM geladen wird
MyClass
?Also ab dem 4. Punkt, wenn Sie
MyClass.foo()
von Kotlin oderMyClass.Companion.foo()
an diesem Punkt tun,MyClass
wird geladen und bereit. (Wahrscheinlich viel zu früh)Bitte beachten Sie, dass zu diesem Zeitpunkt kein Objekt
MyClass
existiert, dh wir haben keinen Ausdruck verwendetMyClass()
.Bedeutet dies, dass
static
Felder so lange im Speicher bleiben, wie die Anwendung ausgeführt wird?Sie können Müll gesammelt werden, wenn der deklarierende Typ entladen wird. In unserem Fall, wenn JVM oder ART (auf Android) entladen werden,
MyClass
besteht die Möglichkeit, dass das Begleitobjekt Müll gesammelt wird.JVM Spec hat Folgendes zum Entladen von Klassen zu sagen
In der praktischen Klasse kommt das Entladen fast (ich sagte fast) nie vor, also bleiben Begleitobjekte für den Lebenszyklus der App im Speicher .
quelle