Pergunta

Será que a máquina virtual Java nunca mover objetos na memória, e se assim for, como é que lidar com atualizar as referências ao objeto movido?

Eu pergunto porque eu estou explorando uma idéia de armazenar objetos em uma forma distribuída (ex. Em vários servidores), mas eu preciso a capacidade de mover objetos entre servidores por razões de eficiência. Objetos precisam ser capaz de conter ponteiros para cada-outro, mesmo para objetos em servidores remotos. Estou tentando pensar na melhor maneira de referências de atualização para objetos movidos.

As minhas duas ideias até agora são:

  1. Mantenha um em algum lugar indireto de referência que não se move para a vida útil do objeto, que nós atualizamos se o objeto se move. Mas - como são esses indireções gerenciada
  2. Mantenha uma lista de referências reversa com cada objeto, por isso sabemos o que tem que ser atualizado se o objeto é movido. Claro, isso cria uma sobrecarga de desempenho.

Eu estaria interessado em feedback sobre essas abordagens, e quaisquer sugestões para abordagens alternativas.

Foi útil?

Solução

Em referência ao comentário acima sobre a pé do monte.

Diferentes do GC fazê-lo de diferentes maneiras.

copiar Normalmente coletores quando andam a pilha, eles não andam todos os objetos na pilha. Ao contrário, eles andam os objetos vivem na pilha. A implicação é que, se é acessível a partir do objeto "root", o objeto é ao vivo.

Assim, nesta fase é tem que tocar todos os objetos ao vivo de qualquer maneira, como ele copia-los da pilha velha para a nova pilha. Uma vez que a cópia dos objetos vivos é feito, tudo o que resta na pilha velha são ou já objetos copiados, ou lixo. Nesse ponto, a pilha velha pode ser descartada completamente.

Os dois principais benefícios deste tipo de coletor são de que ele compacta o heap durante a fase de cópia, e que apenas copia objetos vivos. Isso é importante para muitos sistemas, porque com este tipo de coletor, alocação de objeto é sujeira barato, literalmente, pouco mais do que incrementar um ponteiro de pilha. Quando GC acontece, nenhum dos objetos "mortos" são copiados, para que eles não retardar o coletor para baixo. Nota-se também em sistemas dinâmicos que há muito mais pequena, o lixo temporário, do que há longa data de lixo.

Além disso, andando o gráfico do objeto ao vivo, você pode ver como o GC pode "saber" sobre cada objeto, e acompanhá-los para qualquer ajuste de endereço fins realizada durante a cópia.

Este não é o fórum para conversar profundamente sobre a mecânica de GC, como é um problema não-trivial, mas isso é o básico de como uma cópia de obras coletor.

A geracional copiar GC vai colocar objetos "mais velhos" em diferentes montes, e aqueles acabam sendo coletadas com menos frequência do que montes "mais recentes". A teoria é que os objetos de longa duração são promovidos para as gerações mais velhas e se recolheu cada vez menos, melhorando o desempenho geral GC.

Outras dicas

(praticamente) Qualquer sistema coletadas de lixo tem que mover objetos na memória para embalá-los mais densa e problemas evitar a fragmentação.

O que você está olhando é um assunto muito grande e complexo. Eu sugiro que você leia sobre existente estilo de objeto remoto da API: .NET comunicação remota e indo mais tecnologias de volta como CORBA

Qualquer solução para rastrear as referências será complicado por ter que lidar com todos os modos de falha que existem em sistemas distribuídos. Será que a JVM não tem que se preocupar repente encontrar que não pode ver metade de sua pilha porque um switch de rede glitched.

Quando você furar o projeto que eu acho que um monte de que virá para baixo a como você deseja lidar com diferentes casos de falha.

resposta aos comentários:

sua pergunta fala sobre o armazenamento de objetos em uma forma distribuída, que é exatamente o .NET comunicação remota e CORBA endereço. É certo que nem suporta a tecnologia de migração desses objetos (AFAIK). Mas ambos lidam intensamente com os conceitos de identidade de objeto que é uma parte crítica de qualquer sistema de objetos distribuídos:. Como as diferentes partes do saber sistema que objetos que estão falando

Eu não sou muito familiarizado com os detalhes do coletor de lixo Java, e eu tenho certeza que os coletores de lixo Java e .NET tem um monte de complexidade neles para obter o máximo desempenho com o mínimo impacto sobre a aplicação.

No entanto, a idéia básica para coleta de lixo é:

  • O VM pára os tópicos a execução de código gerenciado
  • Ele executa uma análise de acessibilidade do conjunto de 'raízes' conhecidos: variáveis ??estáticas, variáveis ??locais em todos os segmentos. Para cada objeto que encontra segue-se todas as referências dentro do objeto.
  • Qualquer objeto não identificado pela análise de acessibilidade é lixo.
  • Os objetos que ainda estão vivos pode então ser movido para baixo na memória para embalá-los densamente. Isto significa que todas as referências a esses objetos também devem ser atualizados com o novo endereço. Ao controlar quando uma coleta de lixo pode ocorrer a VM é capaz de garantir que não existem referências de objeto 'in-the-air' (isto é. Que está sendo realizada em um registo de máquina) que causaria um problema.
  • Uma vez que o processo está completo o VM começa os tópicos executar novamente.

Como um refinamento deste processo, o VM pode executar a coleta de lixo geracional, onde pilhas separadas são mantidos com base na 'idade' de um objeto. Objetos começam na pilha 0 e se eles sobrevivem vários GCs então a migrar para montão 1 e, eventualmente, a pilha 2 (e assim por diante - .NET suporta 3 gerações única embora). A vantagem disto é que o GC pode executar pilha 0 coleções com muita freqüência, e não precisa se preocupar em fazer o trabalho para provar os objetos de vida longa (que acabaram em pilha 2) ainda estão vivos (o que quase certamente são) .

Existem outros refinamentos para apoiar a coleta de lixo concorrente, e detalhes em torno de tópicos que são realmente executar código não gerenciado quando o GC está programado que acrescentar muito mais complexidade a esta área.

Eu seria curioso para saber mais sobre suas necessidades. Como outra resposta sugere, Terracotta pode ser exatamente o que você está procurando.

Há uma sutil diferença entre o que no entanto Terracotta fornece, eo que você está pedindo, assim, o meu inquérito.

A diferença é que, tanto quanto você está preocupado, Terracotta não fornece "remotas" referências a objetos - na verdade, todo o "controle remoto" noção de RMI, JMS, etc. é inteiramente ausente ao usar Terracotta

Em vez disso, em terracota, todos os objetos residem em grande pilha virtual. Tópicos, quer no nó 1, ou Node 2, Node 3, Nó 4, etc todos têm acesso a qualquer objeto na pilha virtual.

Não há nenhuma programação especial para aprender, ou APIs especiais, objetos no "virtual" pilha tem exatamente o mesmo comportamento como objetos na pilha local.

Em suma, o que Terracotta fornece um modelo de programação para várias JVMs que opera exatamente o mesmo que um modelo de programação para uma única JVM. Tópicos no nós separados simplesmente se comportar como threads em um único nó - mutações objeto, sincronizados, espera, notificar todos se comportam exatamente o mesmo em nós como como entre segmentos -. Não há diferença

Além disso, ao contrário de qualquer solução para vir antes dele, referências de objeto são mantidas entre os nós - ou seja, você pode usar ==. É tudo uma parte da manutenção do modelo de memória Java em todo o cluster que é o requisito fundamental para tornar o trabalho "regular" Java (por exemplo POJOs, sincronizado, espera / notificar) (nenhum de que as obras se você não / não pode preservar identidade do objeto através do cluster).

Portanto, a questão volta para você para refinar ainda mais seus requiements -? Para quê você precisa "remota" ponteiros

A palavra-chave que você está depois é "coletor de lixo de compactação". JVMs estão autorizados a usar um, o que significa que os objetos podem ser realocados. Consulte o seu JVM manual para descobrir se o seu faz, e ver se existem opções de linha de comando que o afectam.

A forma conceitualmente mais simples de explicar compactação é assumir que o coletor de lixo congela os tópicos, muda o objeto, pesquisas heap e pilha para todas as referências a esse objeto, e atualiza-los com o novo endereço. Na verdade, é mais complexo do que isso, uma vez que, por razões de desempenho que você não deseja executar uma varredura completa com tópicos paralisadas, portanto, um coletor de lixo incremental fazer um trabalho em preparação para a compactação sempre que pode.

Se você estiver interessado em referências indiretas, você poderia começar por pesquisar referências fracas e moles em Java, e também as referências remotas utilizados por vários sistemas RPC.

Parece que você está procurando um cache distribuído, algo como terracota ou oráculo de java objece cache (anteriormente tangersol).

Se você está disposto a ir tão bem no fundo, você pode dar uma olhada para JBoss Cache arquitetura docs e agarrar um pouco do seu código-fonte como referência.

Este não é exatamente o que você descreveu, mas funciona muito semelhante.

Aqui está o link.

http://www.jboss.org/jbosscache/

Espero que isso ajude.

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