Eu estava navegando em alguns livros antigos e encontrei uma cópia de "Java Prático" de Peter Hagger. Na seção de desempenho, há uma recomendação para definir referências de objeto null
quando não forem mais necessárias.
Em Java, definir referências de objeto para null
melhorar o desempenho ou a eficiência da coleta de lixo? Em caso afirmativo, em que casos isso é um problema? Classes de contêiner? Composição do objeto? Classes internas anônimas?
Eu vejo isso no código com bastante frequência. Este conselho de programação agora é obsoleto ou ainda é útil?
Respostas:
Depende um pouco de quando você estava pensando em anular a referência.
Se você tiver uma cadeia de objetos A-> B-> C, uma vez que A não seja alcançável, A, B e C serão todos elegíveis para a coleta de lixo (assumindo que nada mais está se referindo a B ou C). Não há necessidade, e nunca houve necessidade, de definir explicitamente as referências A-> B ou B-> C como nulas, por exemplo.
Tirando isso, na maioria das vezes o problema realmente não surge, porque na realidade você está lidando com objetos em coleções. Geralmente, você deve sempre pensar em remover objetos de listas, mapas etc. chamando o método remove () apropriado.
O caso em que costumava haver algum conselho para definir referências para nulo foi especificamente em um escopo longo, onde um objeto de uso intensivo de memória deixou de ser usado no meio do escopo . Por exemplo:
O raciocínio aqui era que, como obj ainda está no escopo, sem o anular explícito da referência, ele não se torna o lixo coletável até que o método doSomethingElse () seja concluído. E este é o conselho que provavelmente não se aplica mais às JVMs modernas : acontece que o compilador JIT pode descobrir em que ponto uma determinada referência de objeto local não é mais usada.
fonte
Não, não é um conselho obsoleto. Referências pendentes ainda são um problema, especialmente se você estiver, digamos, implementando um contêiner de matriz expansível (
ArrayList
ou semelhante) usando uma matriz pré-alocada. Elementos além do tamanho "lógico" da lista devem ser anulados, ou então não serão liberados.Consulte Effective Java 2ª ed, Item 6: Eliminate Obsolete Object References.
fonte
Campos de instância, elementos de matriz
Se houver uma referência a um objeto, ele não pode ser coletado como lixo. Especialmente se esse objeto (e todo o gráfico por trás dele) for grande, há apenas uma referência que está interrompendo a coleta de lixo e essa referência não é mais necessária, o que é uma situação lamentável.
Casos patológicos são o objeto que retém uma instância não missária para toda a árvore XML DOM que foi usada para configurá-lo, o MBean que não foi cancelado ou a única referência a um objeto de um aplicativo da web não implantado que impede que um carregador de classe inteiro seja descarregado .
Portanto, a menos que você tenha certeza de que o objeto que contém a própria referência será coletado como lixo de qualquer maneira (ou mesmo assim), você deve anular tudo o que não é mais necessário.
Variáveis com escopo:
Se você está considerando definir uma variável local como nula antes do final de seu escopo, para que ela possa ser recuperada pelo coletor de lixo e marcá-la como "inutilizável de agora em diante", você deve considerar colocá-la em um escopo mais limitado. .
torna-se
Escopos longos e simples geralmente são ruins para a legibilidade do código também. A introdução de métodos privados para separar as coisas apenas para esse propósito também não é algo inédito.
fonte
Em ambientes com restrição de memória (por exemplo, telefones celulares), isso pode ser útil. Definindo null, o objeto não precisa esperar que a variável saia do escopo para ser gc'd.
Para a programação diária, entretanto, esta não deve ser a regra, exceto em casos especiais como o que Chris Jester-Young citou.
fonte
Em primeiro lugar, não significa nada para o qual você está definindo um objeto
null
. Eu explico abaixo:No segmento de código acima, estamos criando o nome
list1
da variável de referência doArrayList
objeto do objeto que está armazenado na memória. Entãolist1
está se referindo a esse objeto e ele nada mais do que uma variável. E na segunda linha de código, estamos copiando a referência delist1
paralist2
. Agora, voltando à sua pergunta se eu faço:isso significa que
list1
não está mais se referindo a nenhum objeto armazenado na memória, entãolist2
também não terá nada para se referir. Portanto, se você verificar o tamanho delist2
:Então aqui chega o conceito de coletor de lixo que diz «nada para se preocupar em liberar a memória que é mantida pelo objeto, farei isso quando descobrir que ele não será mais usado no programa e o JVM me gerenciará.»
Espero que o conceito esteja claro.
fonte
Um dos motivos para isso é eliminar referências de objetos obsoletos. Você pode ler o texto aqui.
fonte