Quais são as vantagens e desvantagens de se ter marca de bits juntos e separados para Coleta de Lixo

StackOverflow https://stackoverflow.com//questions/23057531

Pergunta

Eu estava assistindo o vídeo O Google IO de 2008 - Dalvik Virtual Machine Internas para entender como Dalvik VM funciona e por que aquelas pessoas tem preferido Dalvik VM através de JVM para o android.Eu achei que o android usa memória separado para o Lixo, de informações sobre os objetos , em oposição a JVM onde nós temos a marca de bits(bits dizer se o objeto é capaz de garbagfe coleção ou não) juntamente com os objetos.

Alguém pode me dizer em detalhes quais são as vantagens e desvantagens de se ter separado de memória para marcas de bits e não ter memória separado para marcar bits ?

Eu era incapaz de obter essa diferença por assistir o vídeo.

Foi útil?

Solução

Algumas vantagens de um bitmap separado:

  • muito mais denso. Um GC típico precisa de talvez oito bits de metadados GC, mas devido ao alinhamento um cabeçalho no objeto pode arredondar esta memória até 32 bits.
  • Algumas operações, em particular ao redor de varrer, se tornam mais rápidas. Isso é parcialmente porque o bitmap mais denso (veja) significa menos tráfego de memória e melhor uso de cache, mas também porque algumas operações (e. Zerar todos os bits de marca) podem ser vetorizadas quando neste formato. (Outras partes do GC precisam ser projetadas para fazer uso dessa habilidade.)
  • Se você geraracodiceCode em um sistema UNIX, um bitmark separado faz uso melhor de cópia-liga: as páginas contendo objetos podem permanecer compartilhadas.

Algumas vantagens dos bits de marca no objeto:

  • Dependendo do esquema usado para associar objetos com bitmaps, obter o bit de marca para um objeto e vice-versa pode ser bastante complicado e / ou lento. Um cabeçalho em objeto, por outro lado, é trivial para acessar.
  • Management de memória mais fácil: Não há necessidade de criar uma alocação separada do tamanho certo e mantê-lo em sincronia.
  • Muitos esquemas rápidos para encontrar bitmaps para objetos e vice-versa são bastante restritivos em outros cumprimentos. Por exemplo, se você criar um bitmap para cada página e armazenar o ponteiro de bitmap no início da página, você terá um problema ao armazenar objetos maiores que uma página.

Outras dicas

Separado marca de bits trabalho por ter uma matriz de bits, onde cada bit representa um endereço na pilha de que pode iniciar um objeto.Por exemplo, suponha que a pilha é 65536 bytes e todos os objetos estão alinhados às 16 limites de byte e, em seguida, há 4096 endereços na pilha que pode ser o início de um objeto.Isso significa que a matriz deve conter 4096 bits, que pode ser eficientemente armazenado como 512 bytes ou 64 64 bits de tamanho inteiros.

Em objeto de interrogação bits funciona por ter um pouco de cada um cabeçalho de cada objeto ser definido como 1 se o objeto for marcado e 0 caso contrário.Note que isto requer que cada objeto tem um dedicado área de cabeçalho.Tempos de execução, como a JVM e .NET adicionar cabeçalhos de objetos para você obter essencialmente o espaço para a marca pouco de graça.

Mas ele não funciona para conservador de colecionadores que não tem controle total do seu ambiente de execução, tais como o Boehm GC.Eles podem misidentify inteiros como os ponteiros, então, para eles modificar qualquer coisa no mutadores de dados heap é arriscado.

Marca & varrer a coleta de lixo é dividido em duas fases:marcação e de varrição.Marcação usando o no-objeto marca de bits é direta (pseudo-código):

if not obj.is_marked():
    obj.mark()
    mark_stack.append(obj)

Usando uma matriz separada para armazenar marca de bits, temos de converter os objetos de endereço e tamanho para índices na matriz de bits e definir os bits correspondentes às 1:

obj_bits = obj.size_in_bytes() / 16
bit_idx = (obj - heap.start_address()) / 16
if not bitarr.bit_set(bit_idx):
    bitarr.set_range(bit_idx, obj_bits)
    mark_stack.append(obj)

Assim, em nosso exemplo, se um objeto é de 128 bytes de comprimento, 8 bits será definido na matriz de bits.Claramente, utilizando o objeto marca de bits é muito mais simples.

Mas separada marca de bits de ganhar alguma força quando a varrer.Varrendo envolve a digitalização através de toda a pilha e encontrar contínua de regiões de memória que não está marcado e, portanto, pode ser recuperada.Utilizando o objecto de marca bits, seria cerca de olhar como este:

iter = heap.start_address()
while iter < heap.end_address():
    # Scan til the next unmarked object
    while iter.is_marked():
        iter.unmark()
        iter += iter.size()
        if iter == heap.end_address():
            return
    # At an unmarked block
    start = iter
    # Scan til the next marked object
    while iter < heap.end_address() and not iter.is_marked():
        iter += iter.size()
    size = iter - start
    # Reclaim the block
    heap.reclaim(start, size)

Observe como a iteração saltos do objeto no iter += iter.size() linhas.Isso significa que a varredura de fase de tempo de execução é proporcional ao número total de viver e de lixo de objetos.

Utilizando-se separar marca de bits, o que você faria praticamente o mesmo ciclo, exceto que grandes porções de lixo de objetos seria hasteada sem "parar" em cada um deles.

Considere o 65536 pilha novamente.Suponha que ele contém 4096 objetos que são lixo.Iteração 64 64 bits inteiros na marca de bits matriz e vendo que eles são todos 0 é, obviamente, muito rápido.Portanto, a varrição de fase pode ser potencialmente muito mais rápido separado com marca de bits.

Mas há uma outra questão!Em qualquer marca e varrer coletor, o tempo de execução é dominada pela marca de fase e não a varrer fase, que é geralmente muito rápida.Assim, o veredicto é ainda para fora.Alguns preferem separar marca de bits, outros preferem no objeto queridos.Para o melhor de meu conhecimento, ninguém ainda foi capaz de mostrar que a abordagem é superior ao outro.

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