No Kotlin, você pode criar um singleton usando um objeto complementar:
class MyClass {
companion object {
fun doSomething() {
}
}
}
De acordo com os documentos da Kotlin, ele afirma:
Observe que, mesmo que os membros dos objetos complementares pareçam membros estáticos em outros idiomas, em tempo de execução, eles ainda são membros da instância de objetos reais ...
https://kotlinlang.org/docs/reference/object-declarations.html
Isso significa que, depois de usar uma função no objeto complementar, a instância da classe (MyClass) permanece na memória durante todo o ciclo de vida do aplicativo? Existe uma maneira no Android Studio de verificar se esse é o caso?
Respostas:
Objeto complementar na JVM
em kotlin
MyClass (Kotlin) convertido na JVM
Como o código acima,
companion object
é declarado comoCompanion
classe na JVM e é criado comostatic
campo dentro daMyClass
classe. Assim, não é coletado pelo gc. Portanto, a memória do objeto (Companion) é mantida durante oProcessLifecycle
.static final object
não é liberado no caso normal.Em conclusão, se referida à
MyClass.Companion
instância no aplicativo, essa instância não será coletada como lixo. (em Classloaders gerais).* Se não for referido à
MyClass.Companion
instância no aplicativo, poderá ser removido pelo recurso de redução de código .Você pode ver através do android studio> profiler> Heap dump.
Referência
fonte
Como você parece saber, a resposta acima também deixa claro que os objetos complementares são traduzidos para classes, e a classe que os declara mantém uma referência estática ao objeto da classe complementar, algo como a seguir:
Agora a pergunta
como a classe declarante possui uma
static
referência à classe complementar, a pergunta se reduz ao tempo de vida dosstatic
campos na jvmclass
e a resposta está na especificação da JVM , mas a especificação é um pouco seca na explicação, por isso estou adicionando alguns trechos do livro Inside a Java Virtual Machine .Como no seu exemplo, digamos que temos um
class
objeto complementar com nada além de um único.A primeira pergunta é quando um objeto da classe complementar será criado? ou quando os
static
campos são inicializados?texto relevante do livro . (por contexto, o livro está falando sobre o procedimento de carregamento de classe)
Portanto, sabemos que, uma vez
MyClass
carregado e inicializado, o objeto da classe complementar será criado.mas o que causaria o carregamento da JVM
MyClass
?Portanto, conforme o quarto ponto, quando você faz
MyClass.foo()
do kotlin ouMyClass.Companion.foo()
, nesse momento,MyClass
ele estará carregado e pronto. (Provavelmente muito cedo)Observe que, neste ponto, nenhum objeto
MyClass
existe, ou seja, não usamos expressãoMyClass()
.Isso significa que os
static
campos permanecerão na memória enquanto o aplicativo estiver em execução?Eles podem ser coletados como lixo se o tipo de declaração for descarregado; no nosso caso, se a JVM ou ART (no android) descarregar
MyClass
, existe a possibilidade de que o objeto complementar seja coletado como lixo.A JVM Spec tem o seguinte a dizer sobre o descarregamento de classe
Na aula de praticidade, o descarregamento quase (eu disse quase) nunca acontece; portanto , os objetos complementares permanecerão na memória durante o ciclo de vida do aplicativo .
fonte