En Kotlin, puede crear un singleton usando un objeto complementario:
class MyClass {
companion object {
fun doSomething() {
}
}
}
Según los documentos de Kotlin, dice:
Tenga en cuenta que, aunque los miembros de los objetos complementarios se vean como miembros estáticos en otros idiomas, en el tiempo de ejecución siguen siendo miembros de objetos reales ...
https://kotlinlang.org/docs/reference/object-declarations.html
¿Significa esto que después de usar una función en el objeto complementario, la instancia de la clase (MyClass) permanece en la memoria durante todo el ciclo de vida de la aplicación? ¿Hay alguna manera en Android Studio para verificar si este es el caso?
Respuestas:
Objeto complementario en JVM
en kotlin
MyClass (Kotlin) convertido en JVM
Como el código anterior,
companion object
se declara comoCompanion
clase en JVM y se crea comostatic
campo dentro de laMyClass
clase. Por lo tanto, no es recolectado por gc. Por lo tanto, la memoria del objeto (Compañero) se mantiene durante elProcessLifecycle
.static final object
no se lanza en el caso normal.En conclusión, si se hace referencia a la
MyClass.Companion
instancia en la aplicación, esa instancia no se recolectará como basura. (en cargadores de clase generales).* Si no se hace referencia a la
MyClass.Companion
instancia en la aplicación, puede eliminarse mediante la función de reducción de código .Puedes ver a través de android studio> profiler> Heap dump.
Referencia
fuente
Como parece saber y la respuesta anterior también deja en claro que los objetos complementarios se traducen a clases, y la clase que los declara tiene una referencia estática al objeto de la clase complementaria, algo como lo siguiente:
Ahora la pregunta
debido a que la clase declarante tiene una
static
referencia a la clase compañera, la pregunta se reduce al tiempo de vida de losstatic
campos en jvmclass
y la respuesta se encuentra en la especificación JVM , pero la especificación es un poco seca en la explicación, así que estoy agregando algunos fragmentos del libro Inside La máquina virtual Java .Como en su ejemplo, digamos que tenemos un
class
objeto que no tiene nada más que compañero.La primera pregunta es cuándo se creará un objeto de clase compañera. o cuando
static
se inicializan los campos?Texto relevante del libro . (por contexto, el libro habla sobre el procedimiento de carga de clases)
Entonces sabemos que una vez que
MyClass
se carga e inicializa, se creará el objeto de la clase complementaria.pero, ¿qué haría que se cargara JVM
MyClass
?Entonces, según el 4to punto cuando lo haga
MyClass.foo()
desde kotlin oMyClass.Companion.foo()
en este puntoMyClass
, estará cargado y listo. (Probablemente mucho antes)Tenga en cuenta que en este momento no
MyClass
existe ningún objeto de existencia, es decir, no hemos utilizado expresiónMyClass()
.¿Significa esto que los
static
campos permanecerán en la memoria mientras la aplicación se esté ejecutando?Se pueden recolectar basura si el tipo de declaración se descarga, en nuestro caso si JVM o ART (en Android) se descargan,
MyClass
entonces existe la posibilidad de que se recolecte basura.JVM Spec tiene lo siguiente que decir sobre la descarga de clases
En la práctica, la descarga de clases casi (dije casi) nunca ocurre, por lo que sí, los objetos complementarios permanecerán en la memoria durante el ciclo de vida de la aplicación .
fuente