Pergunta

Existe uma maneira de criar registrar um manipulador que será chamado exatamente no momento em que a última referência a um determinado objeto é liberado?

Um exemplo seria um objeto que é apoiado por um arquivo de dados físico e uma vez que o objeto se tornar unreferenced, o arquivo deve ser fechado e que renomeado. Seria bom se isso fosse possível sem ter que chamar explicitamente um método "close" no objeto.

Todos os mecanismos de notificação Estou ciente da área Fraco / Fantasma de referência único estado que a notificação ocorrerá em algum ponto no tempo, mas não há nenhuma gurantee a respeito de quando isso vai acontecer ...

Foi útil?

Solução

Em suma, não.

A especificação Java nega-lhe explicitamente a capacidade de saber quando a última referência é liberada. implementações de JVM (e otimizações) dependem desta. Não há gancho.

Outras dicas

No meu entendimento, e eu olhei por algum tempo para encontrar um "destruidor" para objetos java, não há nenhuma maneira de saber quando você perde a última referência. Java rastreia referências a objetos, mas por motivos de desempenho, atualiza essas informações apenas durante a coleta de lixo.

A coisa mais próxima é o método finalize que deve ser chamado durante a coleta de lixo, mas não há nenhuma garantia de que ele será chamado, mesmo assim.

Eu acho WeakReference faz o que quiser. A WeakReference é colocado no ReferenceQueue assim que seus fracamente acessíveis (ou seja, todas as referências fortes são ido).

Veja este artigo por Ethan Nicholas .

Se você está preocupado com algumas referências que não atingem o ReferenceQueue no desligamento, em seguida, manter uma lista de todos os objetos criados (usando WeakReferences ou PhantomReferences). Adicionar um gancho de desligamento que verifica a lista de todas as referências pendentes e realizar qualquer ação que você precisa.

O problema é, "Como você implementar isso, sem algo segurando uma referência para o objeto?"

Mesmo que você poderia ter passado esse problema, dizem com um serviço que vai chamar o HandleManager, o HandleManager teria, então, para criar uma nova referência para o objeto, para passar para o manipulador. Em seguida, o manipulador pode ou (a) armazenar uma referência a ele, que iria confundir o HandleManager que estava esperando para destruir o objeto não referenciado; ou (b) libertar a referência, o que significa que a referência final foi mais uma vez libertado, o que significa que a rotina de tratamento tem de ser chamado novamente ....

Se você precisa para gerenciar recursos externos, como arquivos, o melhor que você pode fazer em java é uma função close () (o nome que você escolher). Você pode usar finalize () como uma apólice de seguro "cinto e suspensórios", mas que tem tempo imprevisível. Portanto, sua principal linha de necessidades de defesa a ser a função close ().

Veja a minha resposta Por que você nunca implementar finalize ()?

Isto não pode ser feito com Java - ele precisa de um coletor de lixo de contagem de referência, tanto quanto eu posso dizer. Você já pensou em abrir e fechar arquivos de dados físicos do seu objeto, conforme necessário, em vez de mantê-la aberta para a vida útil do objeto?

Você pode finalize() override em seu objeto, mas que é problemática por motivos outros já mencionados.

Para o seu exemplo específico, você poderia dar uma olhada em usar algo como File.deleteOnExit() , que iria remover o arquivo uma vez que as saídas de VM.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top