1. Tipo de referência (excluindo uma forte referência)
Pode -se entender que a subclasse direta de referência é processada pela JVM, por isso não tem efeito ao herdar diretamente o tipo de referência no código. Só pode ser herdado de sua subclasse. Os tipos de subclasse correspondentes incluem o seguinte. (Ignore aqueles que não são usados em Java, como Jnireference)
Softreference
Referência fraca
Final Referência
Phantomreference
O tipo de referência acima também é mencionado no Javadoc correspondente. O FinalReference é projetado especialmente para o método Finalize, e existem vários outros cenários de aplicação específicos. Entre eles, a Softreference é usada em caches relacionados à memória, a referência fraca é usada na maioria dos cenários relacionados à reciclagem. O fantasma é usado em cenários de retorno de chamada para reciclagem de objetos de embalagem (como detecção de vazamento de recursos).
Você pode visualizar diretamente as informações da subclasse de vários tipos no IDE para entender quais cenários são usados na maioria das estruturas herdando os tipos correspondentes, para que possamos realmente executar o processamento de seleção de tipo.
2. Construtor de referência
Ele fornece dois construtores internamente, um com uma fila e o outro sem uma fila. O significado da fila é que podemos monitorar essa fila externamente. Ou seja, se um objeto estiver prestes a ser reciclado, o objeto de referência correspondente será colocado nesta fila. Quando obtemos a referência, podemos fazer mais algumas transações.
Se não o fizer, você só pode treinar o objeto de referência continuamente e julgar se o retorno de retorno de retorno nulo (o objeto Phantomreference não pode fazer isso, o Get sempre retorna nulo, por isso possui apenas um construtor com uma fila). Ambos os métodos têm cenários de uso correspondentes, dependendo do aplicativo real. Por exemplo, no fracashashmap, você escolhe consultar os dados da fila para determinar se algum objeto será reciclado. Para threadlocalmap, é usado para determinar se o get () é nulo para processamento.
O construtor correspondente é o seguinte:
Referência (t referência) {this (referente, null);} referência (referência t, referencequeue <? Super t> fila) {this.referent = referent; this.queue = (fila == null)? Referencequeue.null: fila;}A fila nula aqui pode ser entendida como uma fila que não requer nenhum processamento dos dados em sua fila. E não acessará nenhum dado dentro dele.
No objeto acima, a referência representa o objeto que faz referência, ou seja, o objeto em que precisamos ser envolvidos quando o construímos. A definição de que o objeto está prestes a ser reciclado significa que esse objeto não tem outra referência, exceto para referência (não que ele não seja realmente referenciado, mas a acessibilidade do GCROOT é inacessível para evitar o problema da referência circular).
Uma fila é a fila a ser notificada quando o objeto é reciclado. Quando o objeto é reciclado, todo o objeto de referência (não o objeto reciclado) será colocado na fila e, em seguida, os programas externos podem obter os dados correspondentes monitorando esta fila.
3. Referência de referência e cadeia de referência de referência
A fila aqui é nominalmente uma fila, mas não há estrutura de armazenamento real dentro. Seu armazenamento depende do relacionamento entre nós internos. Pode -se entender que a fila é uma estrutura semelhante a uma lista vinculada, e o nó aqui é realmente a própria referência. Pode -se entender que a fila é um contêiner para uma lista vinculada, que armazena apenas o nó da cabeça atual, e os nós subsequentes são mantidos por cada nó de referência até a próxima.
Valor do status de referência
Cada objeto de referência possui uma descrição de estado correspondente, ou seja, ele se descreve e o objeto embrulhado atualmente, para a conveniência de consultar, posicionar ou processamento.
1. Ativo: Estado ativo, ou seja, o objeto correspondente é um forte estado de referência e não foi reciclado. Nesse estado, o objeto não será colocado na fila. Nesse estado, o próximo é nulo, e a fila é a fila referenciada quando é definida.
2. Pendente: prepare -se para colocá -lo na fila. Nesse estado, os objetos a serem processados serão filmados um por um na fila. Durante essa janela de tempo, os objetos correspondentes estão no estado pendente. Independentemente da referência, se você entrar neste estado, poderá pensar que no estado correspondente, o próximo é (definido pela JVM), e a fila é a fila referenciada quando é definida.
3. Encheed: O objeto correspondente já deve ser reciclado e o objeto de referência correspondente foi colocado na fila. O encadeamento externo está pronto para consultar a fila para obter os dados correspondentes. Nesse estado, o próximo é o próximo objeto a ser processado, e a fila é o objeto de identificação especial criado.
4. Inativo: isto é, esse objeto foi recuperado da fila do lado de fora e foi processado. Isso significa que esse objeto de referência pode ser reciclado e o objeto encapsulado internamente também pode ser reciclado (a operação real de reciclagem depende se a ação clara é chamada). Pode -se entender que aqueles que entram nesse estado devem ser reciclados.
A JVM não precisa definir o valor do estado para determinar em qual estado a referência correspondente está. Ela só precisa calcular a próxima e a fila para fazer julgamentos.
4. Referencequeue#Head
Sempre salve o nó mais recente a ser processado na fila atual. Você pode considerar a fila como uma fila de última saída. Quando um novo nó entra, a seguinte lógica é adotada.
newe.Next = Head; Head = Newe;
Então, ao obter, use a lógica correspondente
tmp = head; head = tmp.next; retorna tmp;
V. Referência#a seguir
Ou seja, descreva o próximo nó armazenado pelo nó de referência que está prestes a ser processado. Mas o próximo só fará sentido quando colocado na fila. Para descrever o valor de status correspondente, após ser colocado na fila, sua fila não se referirá mais à fila. Em vez disso, ele se referirá a um envolvimento especial. Por ter sido colocado na fila, não será colocado na fila novamente.
6. Referência#Referente
Ou seja, descreva o objeto real referenciado pela referência atual, que será processada cuidadosamente, conforme declarado na anotação. Ou seja, quando isso será reciclado e, se for reciclado, será diretamente definido como nulo, e programas externos podem aprender com o próprio objeto de referência (em vez de referente) que o comportamento de reciclagem ocorre.
7. Referencequeue#ENQUEUE REFERÊNCIA PENLIDADE
Esse processo é o processo do objeto de referência do ativo-> pendente-> abordado. Este método é processar o objeto que lida com o estado pendente como um estado abrigado. O processo correspondente é a lógica anterior, ou seja, um nó é realizado e o código correspondente é o seguinte.
r.Queue = Enqueed; r.Next = (Head == NULL)? r: head; head = r; Queuelength ++; Lock.NotifyAll ();
A última nitify significa notificar o programa externo que bloqueia a fila atual antes. (Isto é, o objeto pendente não foi obtido antes)
8. Referência#TryHandLepending
Ou seja, ele lida com a mudança do objeto de referência do estado ativo para o estado pendente. Dentro do objeto de referência, há um campo estático, e sua declaração correspondente é a seguinte:
/* Lista de referências esperando para serem inseridas. O colecionador adiciona * referências a esta lista, enquanto o encadeamento do manipulador de referência os remove *. Esta lista está protegida pelo objeto de bloqueio acima. A lista * usa o campo descoberto para vincular seus elementos. */Referência estática privada <Becut> pendente = null;
Pode -se entender que a JVM colocará o objeto a ser processado neste campo estático quando GC. Ao mesmo tempo, outro campo descoberto representa o próximo objeto do objeto a ser processado. Ou seja, pode -se entender que o objeto a ser processado também é uma lista vinculada. Está na fila através da descoberta. Você só precisa continuar pendente e, em seguida, obtenha continuamente o próximo objeto através da descoberta. Como ambos os threads podem acessar esse objeto pendente, é necessário usar o processamento de bloqueio.
O processo de processamento correspondente é o seguinte:
if (pendente! = null) {r = pendente; // 'instanceof' pode lançar um dos membros da Memoryerror às vezes //, então faça isso antes de unir 'r' da cadeia 'pendente' ... C = r Instância do limpador? (Mais limpo) r: nulo; // desvincular 'r' da cadeia 'pendente' pendente = r.Descoberted; r.discovered = null;} // Enqueia o objeto de processamento, ou seja, ele entra no Estado Referencequeue <?? super objeto> q = r.queue; if (q! = referencequeue.null) q.enqueue (r);9. Referência#Limpar
Limpe o objeto original referenciado pelo objeto de referência, para que o objeto original não possa mais ser acessado através do método get (). A partir da ideia de design correspondente, uma vez que ela entrou no objeto da fila, significa que o objeto correspondente precisa ser reciclado porque não há necessidade de acessar o objeto original novamente. Este método não será chamado pela JVM, e a JVM limpa diretamente a referência correspondente através das operações de campo, e sua implementação específica é consistente com o método atual.
A semântica de Clear é anular a referência.
Depois que o objeto de referência fraca entra na fila, a referência correspondente é nula.
Objeto Softreference, se o objeto não entrar na fila quando a memória for suficiente, a referência correspondente não será nula. Se precisar ser processado (memória não suficiente ou outras políticas), a referência correspondente será definida como NULL e depois digite a fila.
Objeto FinalReference, porque ele precisa chamar seu objeto Finalize, mesmo que sua referência seja inserida em uma fila, sua referência não será nula, ou seja, não será limpa.
O objeto Phantomreference, porque o próprio é implementado para retornar nulo, não é muito útil. Porque não será liberado, independentemente de ser um enquadrão ou não.
10. Tópico de enoca referência de manuseio
Como mencionado acima, a JVM definirá o objeto a ser processado no objeto pendente; portanto, deve haver um thread para executar operações contínuas de enquadre. Este encadeamento refere -se ao encadeamento do processador, e sua prioridade é max_priority, ou seja, a mais alta. O processo de inicialização correspondente é criado inicialização estática, que pode ser entendida como quando qualquer objeto ou classe de referência é usado, este thread será criado e iniciado. O código correspondente é o seguinte:
static {threadGroup tg = thread.currentThread (). getThreadGroup (); para (ThreadGroup tgn = tg; tgn! = null; tg = tgn, tgn = tg.getParent ()); Manipulador de thread = new ReferenceHandler (TG, "manipulador de referência"); / * Se houvesse uma prioridade especial apenas do sistema maior que * max_priority, ela seria usada aqui */ Handler.setPriority (Thread.max_priority); Handler.SetDaemon (true); Handler.start ();}Sua prioridade é a mais alta, que pode ser entendida como a necessidade de processar continuamente objetos de referência. Ao imprimir um fio em execução através do JSTack, o manipulador de referência correspondente refere -se ao thread inicializado aqui, como mostrado abaixo:
11. JVM relacionado
Em cada um dos pontos de processamento acima, eles estão relacionados ao processo de reciclagem da JVM. Ou seja, acredita -se que o processo GC funcione em conjunto com a referência correspondente. Por exemplo, usando o coletor do CMS, o processo pré -lema está envolvido em todo o processo mencionado acima, e o processamento de observações da Softreference etc. Ao mesmo tempo, vários processamento do objeto de referência também precisam estar relacionados ao tipo específico. O processamento JVM correspondente usa código C ++, por isso precisa ser cuidadosamente classificado.
12. Resumo
Como o objeto FinalReference, toda a referência e referência são um grupo de grupos de processamento que trabalham juntos. Para garantir diferentes semânticas de referência, o processo relacionado à JVM GC é finalmente realizado para diferentes cenários e diferentes níveis de referência.
Além disso, porque o uso diretamente de referência e os threads de abertura para monitorar as filas é muito problemático e complicado. Você pode consultar o FinalizableReferenceQueee implementado pelo Google Guava e pelo objeto FinizableReference correspondente. O processo de processamento pode ser simplificado um pouco. O exposto acima é o conteúdo inteiro deste artigo, e espero que isso traga alguma ajuda para o aprendizado ou o trabalho de todos.