A referência contando o GC versus o rastreamento do GC é uma propriedade de idioma ou de implementação?

9

Às vezes ouvimos "Swift não faz GC clássico (rastreamento), ele usa ARC".

Mas não tenho certeza se há algo na semântica do Swift que exija contagem de referência. Parece que é possível criar o próprio compilador e tempo de execução Swift para usar o rastreamento de GC.

Então, o que exatamente é "contado por referência" sobre Swift? Implementação da Apple ou a própria linguagem? Existem partes do idioma ou da biblioteca que suportam tão fortemente o ARC que podemos usar esse rótulo para o próprio idioma?

Ray Toal
fonte

Respostas:

9

Swift garante que, uma vez que a última referência a um objeto seja descartada, o objeto seja desinicializado e o deinitcódigo seja executado imediatamente.

Não é possível obter esse tipo de garantia pelo GC - pelo menos não sem sacrificar o desempenho. Os mecanismos padrão do GC apenas garantem a deinitexecução do código, por exemplo, no próximo ciclo do GC. Para uma semântica precisa, você precisa de uma contagem de referência em algum lugar.

chi
fonte
3
Ah, então a presença de deinitcomo uma palavra-chave e sua semântica associada são realmente as coisas que colocam a contagem de referência diretamente no domínio da linguagem, e não na implementação.
quer
2
Nada impede que um tempo de execução GCed verifique objetos inacessíveis sempre que algo é desalocado. É simplesmente terrivelmente ineficiente.
Raphael
@ Rafael Editado para ser mais preciso nesse ponto.
22717 chi
3

O chi respondeu à pergunta específica do corpo sobre o swift, essa resposta responde à pergunta mais geral do título.

A referência contando o GC versus o rastreamento do GC é uma propriedade de idioma ou de implementação?

o GC de contagem de referência e o GC de rastreamento fornecem ao programador garantias diferentes.

A contagem de referência fornece determinismo no local no fluxo do programa em que um objeto é destruído, que pode ser importante se o objeto possuir recursos escassos que devem ser liberados rapidamente. Por outro lado, não pode lidar com ciclos de referências "fortes".

Cabe à especificação de um idioma individual e se alguma característica é garantida e, portanto, quais opções estão disponíveis para uma implementação compatível.

Peter Green
fonte
4
Também é possível combinar refcount e GC. Então a linguagem pode documentar que os objetos têm seu destruidor executado assim que não são referenciados (implicando refcount de uma forma ou de outra) e que os ciclos de referência serão destruídos eventualmente (implicando alguma forma de GC). Como alternativa, a implementação pode fazer isso enquanto a linguagem não garante quando os destruidores são executados (IIRC é o caso do Python e sua implementação de referência); nesse caso, seria uma propriedade de implementação.
Gilles 'SO- stop be evil'
1

Você pode pegar o idioma conhecido como Swift e renomeá-lo para "Swift with ARC". Você pode criar um novo idioma chamado "Swift with GC" com exatamente a mesma sintaxe, mas com menos garantias sobre quando os objetos são desalocados.

No Swift with ARC, quando a contagem de referência for 0, o objeto irá. Com a coleta de lixo, desde que você tenha uma referência fraca, você pode atribuir essa referência fraca a uma referência forte para "recuperar" o objeto. (No Swift, quando a contagem de referências é 0, as referências fracas são nulas); essa é uma grande diferença.

E é claro que o Swift with ARC garante que a eliminação da última contagem de referência desalocará o objeto imediatamente. Por exemplo, você pode ter uma classe FileWriter, na qual você não tem permissão para ter duas instâncias gravando no mesmo arquivo ao mesmo tempo. Em Swift with ARC, você poderia dizer oldWriter = nil; newWriter = FileWriter (...) e você saberia que o novo FileWriter é criado apenas após a exclusão do antigo (a menos que você tenha mantido outra referência); no Swift com GC isso não funcionaria.

Outra diferença é que, em "Swift with ARC", objetos que são referenciados apenas através de ciclos de referência fortes, mas que na verdade não são alcançáveis, têm garantia de não serem desalocados.

gnasher729
fonte