Alguém pode me explicar brevemente como o ARC funciona? Sei que é diferente da Garbage Collection, mas estava me perguntando exatamente como funcionava.
Além disso, se o ARC faz o que o GC faz sem prejudicar o desempenho, por que o Java usa o GC? Por que não usa o ARC também?
Respostas:
Todo novo desenvolvedor que chega ao Objective-C precisa aprender as regras rígidas de quando reter, liberar e liberar objetos automaticamente. Essas regras até especificam convenções de nomenclatura que implicam a contagem de retenção de objetos retornados dos métodos. O gerenciamento de memória no Objective-C se torna uma segunda natureza quando você leva essas regras a sério e as aplica de maneira consistente, mas mesmo os desenvolvedores de cacau mais experientes desaparecem de tempos em tempos.
Com o Clang Static Analyzer, os desenvolvedores do LLVM perceberam que essas regras eram confiáveis o suficiente para criar uma ferramenta para apontar vazamentos de memória e liberações excessivas nos caminhos que seu código segue.
A contagem automática de referência (ARC) é o próximo passo lógico. Se o compilador puder reconhecer onde você deve reter e liberar objetos, por que não inserir esse código para você? Tarefas rígidas e repetitivas são ótimas para compiladores e seus irmãos. Os seres humanos esquecem as coisas e cometem erros, mas os computadores são muito mais consistentes.
No entanto, isso não o libera completamente de se preocupar com o gerenciamento de memória nessas plataformas. Descrevo a questão principal a ser observada (reter ciclos) na minha resposta aqui , o que pode exigir um pouco de sua parte para marcar indicadores fracos. No entanto, isso é menor quando comparado ao que você está ganhando no ARC.
Quando comparado ao gerenciamento manual de memória e coleta de lixo, o ARC oferece o melhor dos dois mundos, eliminando a necessidade de escrever um código de retenção / liberação, mas sem os perfis de memória de parada e dente de serra vistos em um ambiente de coleta de lixo. As únicas vantagens da coleta de lixo são a capacidade de lidar com ciclos de retenção e o fato de as atribuições de propriedades atômicas serem baratas (como discutido aqui ). Sei que estou substituindo todo o meu código existente do Mac GC por implementações ARC.
Quanto a isso poder ser estendido para outros idiomas, parece estar voltado para o sistema de contagem de referência no Objective-C. Pode ser difícil aplicar isso ao Java ou a outras linguagens, mas não sei o suficiente sobre os detalhes do compilador de baixo nível para fazer uma declaração definitiva. Dado que a Apple está impulsionando esse esforço no LLVM, o Objective-C virá primeiro, a menos que outra parte comprometa recursos significativos próprios para isso.
A inauguração desses desenvolvedores chocou a WWDC, então as pessoas não estavam cientes de que algo assim poderia ser feito. Pode aparecer em outras plataformas ao longo do tempo, mas, por enquanto, é exclusivo para LLVM e Objective-C.
fonte
O ARC é apenas reproduzir a retenção / liberação antiga (MRC) com o compilador descobrindo quando chamar reter / liberar. Ele tenderá a ter um desempenho mais alto, menor uso de memória de pico e desempenho mais previsível que um sistema de GC.
Por outro lado, alguns tipos de estrutura de dados não são possíveis com o ARC (ou MRC), enquanto o GC pode lidar com eles.
Como exemplo, se você tiver uma classe denominada nó, e o nó tiver um NSArray de filhos e uma única referência ao pai, que "simplesmente funciona" com o GC. Com o ARC (e também com a contagem manual de referências), você tem um problema. Qualquer nó será referenciado de seus filhos e também de seu pai.
Gostar:
Tudo está bem enquanto você estiver usando A (digamos, através de uma variável local).
Quando você terminar com ele (e B1 / B2 / B3), um sistema de GC decidirá, eventualmente, examinar tudo o que encontrar, iniciando nos registros da pilha e da CPU. Ele nunca encontrará A, B1, B2, B3, finalizando-os e reciclando a memória em outros objetos.
Quando você usa ARC ou MRC, e termina com A, ele tem uma refcount de 3 (B1, B2 e B3 todos fazem referência a ele), e B1 / B2 / B3 terá todos uma contagem de referência de 1 (o NSArray de A mantém uma referência a cada). Portanto, todos esses objetos permanecem vivos, mesmo que nada possa usá-los.
A solução comum é decidir que uma dessas referências precisa ser fraca (não contribua para a contagem de referências). Isso funcionará para alguns padrões de uso, por exemplo, se você referenciar B1 / B2 / B3 apenas via A. No entanto, em outros padrões, ele falha. Por exemplo, se você às vezes se apegar a B1 e esperar subir de volta pelo ponteiro pai e encontrar A. Com uma referência fraca, se você se apegar a B1, A pode (e normalmente irá) evaporar e pegar B2 e B3 com isso.
Às vezes, isso não é um problema, mas algumas maneiras muito úteis e naturais de trabalhar com estruturas complexas de dados são muito difíceis de usar com o ARC / MRC.
Portanto, o ARC visa o mesmo tipo de problemas que o GC almeja. No entanto, o ARC trabalha com um conjunto mais limitado de padrões de uso que o GC; portanto, se você pegasse uma linguagem GC (como Java) e enxertasse algo como ARC nela, alguns programas não funcionariam mais (ou pelo menos gerariam toneladas de memória abandonada) , e pode causar sérios problemas de troca ou ficar sem memória ou trocar espaço).
Você também pode dizer que o ARC coloca uma prioridade maior no desempenho (ou talvez previsibilidade), enquanto o GC coloca uma prioridade maior em ser uma solução genérica. Como resultado, o GC possui demandas de CPU / memória menos previsíveis e um desempenho mais baixo (normalmente) que o ARC, mas pode lidar com qualquer padrão de uso. O ARC funcionará muito melhor para muitos padrões de uso comuns, mas para alguns padrões de uso (válidos!), Ele cairá e morrerá.
fonte
foo = nil
.Magia
Mas, mais especificamente, o ARC funciona fazendo exatamente o que você faria com seu código (com algumas pequenas diferenças). O ARC é uma tecnologia de tempo de compilação, diferente do GC, que é de tempo de execução e afetará negativamente seu desempenho. O ARC rastreará as referências a objetos para você e sintetizará os métodos de retenção / liberação / autorelease de acordo com as regras normais. Por esse motivo, o ARC também pode liberar as coisas assim que elas não forem mais necessárias, em vez de jogá-las em um pool de liberação automática apenas para fins de convenção.
Algumas outras melhorias incluem zerar referências fracas, cópia automática de blocos para a pilha, acelerações em geral (6x para pools de liberação automática!).
Uma discussão mais detalhada sobre como tudo isso funciona é encontrada nos Documentos do LLVM no ARC.
fonte
Varia muito da coleta de lixo. Você já viu os avisos que indicam que você pode estar vazando objetos em linhas diferentes? Essas instruções até dizem em qual linha você alocou o objeto. Isso deu um passo adiante e agora pode inserir
retain
/release
instruções nos locais apropriados, melhores do que a maioria dos programadores, quase 100% do tempo. Ocasionalmente, existem algumas instâncias estranhas de objetos retidos com as quais você precisa ajudá-lo.fonte
Muito bem explicado pela documentação do desenvolvedor da Apple. Leia "Como o ARC funciona"
Conhecer Diff. entre coleta de lixo e ARC: Leia isto
fonte
O ARC é um recurso do compilador que fornece gerenciamento automático de memória de objetos.
Em vez de você precisar se lembrar de quando usar
retain, release
, oautorelease
ARC avalia os requisitos de vida útil de seus objetos e insere automaticamente as chamadas de gerenciamento de memória apropriadas para você no momento da compilação. O compilador também gera métodos de desalocação apropriados para você.O compilador insere as
retain/release
chamadas necessárias em tempo de compilação, mas essas chamadas são executadas em tempo de execução, como qualquer outro código.O diagrama a seguir forneceria uma melhor compreensão de como o ARC funciona.
Aqueles que são novos no desenvolvimento do iOS e não têm experiência de trabalho no Objetivo C. Consulte a documentação da Apple para o Advanced Memory Management Programming Guide para entender melhor o gerenciamento de memória.
fonte