Quelqu'un peut-il m'expliquer brièvement comment fonctionne l'ARC? Je sais que c'est différent de Garbage Collection, mais je me demandais exactement comment cela fonctionnait.
De plus, si ARC fait ce que fait GC sans entraver les performances, alors pourquoi Java utilise-t-il GC? Pourquoi n'utilise-t-il pas également ARC?
Réponses:
Chaque nouveau développeur qui vient à Objective-C doit apprendre les règles rigides de la conservation, de la libération et de la libération automatique des objets. Ces règles spécifient même des conventions de dénomination qui impliquent le nombre de rétention d'objets renvoyés par les méthodes. La gestion de la mémoire dans Objective-C devient une seconde nature une fois que vous prenez ces règles à cœur et les appliquez de manière cohérente, mais même les développeurs Cocoa les plus expérimentés glissent de temps en temps.
Avec l'analyseur statique Clang, les développeurs LLVM ont réalisé que ces règles étaient suffisamment fiables pour pouvoir construire un outil pour signaler les fuites de mémoire et les libérations excessives dans les chemins empruntés par votre code.
Le comptage automatique des références (ARC) est la prochaine étape logique. Si le compilateur peut reconnaître où vous devez conserver et libérer des objets, pourquoi ne pas lui faire insérer ce code pour vous? Les tâches rigides et répétitives sont ce que les compilateurs et leurs frères sont grands. Les humains oublient des choses et font des erreurs, mais les ordinateurs sont beaucoup plus cohérents.
Cependant, cela ne vous libère pas complètement du souci de la gestion de la mémoire sur ces plateformes. Je décris le problème principal à surveiller (conserver les cycles) dans ma réponse ici , qui peut nécessiter un peu de réflexion de votre part pour marquer les pointeurs faibles. Cependant, c'est mineur par rapport à ce que vous gagnez dans ARC.
Par rapport à la gestion manuelle de la mémoire et à la récupération de place, ARC vous offre le meilleur des deux mondes en supprimant la nécessité d'écrire du code de conservation / libération, sans pour autant avoir les profils de mémoire d'arrêt et en dents de scie vus dans un environnement de récupération de place. Les seuls avantages de la récupération de place par rapport à cela sont sa capacité à gérer les cycles de rétention et le fait que les affectations de propriétés atomiques sont peu coûteuses (comme expliqué ici ). Je sais que je remplace tout mon code Mac GC existant par des implémentations ARC.
Quant à savoir si cela pourrait être étendu à d'autres langues, il semble axé sur le système de comptage des références dans Objective-C. Il pourrait être difficile de l'appliquer à Java ou à d'autres langages, mais je ne connais pas suffisamment les détails du compilateur de bas niveau pour y faire une déclaration définitive. Étant donné qu'Apple est celui qui pousse cet effort dans LLVM, Objective-C passera en premier, à moins qu'une autre partie n'engage des ressources importantes pour cela.
Le dévoilement de ces développeurs choqués à la WWDC, donc les gens ne savaient pas que quelque chose comme ça pouvait être fait. Il peut apparaître sur d'autres plates-formes au fil du temps, mais pour l'instant, il est exclusif à LLVM et Objective-C.
la source
ARC est juste un ancien jeu de retenue / libération (MRC) avec le compilateur qui détermine quand appeler la conservation / libération. Il aura tendance à avoir des performances plus élevées, une utilisation maximale de la mémoire de pointe et des performances plus prévisibles qu'un système GC.
En revanche, certains types de structure de données ne sont pas possibles avec ARC (ou MRC), tandis que GC peut les gérer.
Par exemple, si vous avez une classe nommée node et que node a un NSArray d'enfants et une seule référence à son parent qui "fonctionne" avec GC. Avec ARC (et le comptage manuel des références également), vous avez un problème. Tout nœud donné sera référencé à partir de ses enfants et également de son parent.
Comme:
Tout va bien lorsque vous utilisez A (disons via une variable locale).
Lorsque vous en aurez terminé (et B1 / B2 / B3), un système GC décidera éventuellement de regarder tout ce qu'il peut trouver à partir de la pile et des registres CPU. Il ne trouvera jamais A, B1, B2, B3, il les finalisera donc et recyclera la mémoire en d'autres objets.
Lorsque vous utilisez ARC ou MRC et que vous finissez avec A, il a un décompte de 3 (B1, B2 et B3 le référencent tous), et B1 / B2 / B3 aura tous un décompte de référence de 1 (le NSArray de A contient une référence à chaque). Tous ces objets restent donc vivants même si rien ne peut jamais les utiliser.
La solution courante consiste à décider que l'une de ces références doit être faible (ne pas contribuer au décompte des références). Cela fonctionnera pour certains modèles d'utilisation, par exemple si vous référencez B1 / B2 / B3 uniquement via A. Cependant, dans d'autres modèles, cela échoue. Par exemple, si vous vous accrocherez parfois à B1 et que vous vous attendez à remonter via le pointeur parent et à trouver A. Avec une référence faible si vous ne maintenez que B1, A peut (et normalement va) s'évaporer et prendre B2 et B3 avec ça.
Parfois, ce n'est pas un problème, mais certaines façons très utiles et naturelles de travailler avec des structures de données complexes sont très difficiles à utiliser avec ARC / MRC.
L'ARC cible donc le même type de problèmes que le GC cible. Cependant, ARC fonctionne sur un ensemble de modèles d'utilisation plus limité que GC, donc si vous preniez un langage GC (comme Java) et y greffiez quelque chose comme ARC, certains programmes ne fonctionneraient plus (ou du moins généreraient des tonnes de mémoire abandonnée). et peut entraîner de graves problèmes de permutation ou manquer de mémoire ou d'espace d'échange).
Vous pouvez également dire que l'ARC accorde une plus grande priorité aux performances (ou peut-être à la prévisibilité) tandis que GC accorde une plus grande priorité à une solution générique. Par conséquent, GC a des demandes CPU / mémoire moins prévisibles et des performances (normalement) inférieures à ARC, mais peut gérer n'importe quel modèle d'utilisation. ARC fonctionnera beaucoup mieux pour de nombreux modèles d'utilisation courants, mais pour quelques modèles d'utilisation (valides!), Il tombera et mourra.
la source
foo = nil
.la magie
Mais plus spécifiquement, ARC fonctionne en faisant exactement ce que vous feriez avec votre code (avec certaines différences mineures). ARC est une technologie de compilation, contrairement à GC qui est l'exécution et aura un impact négatif sur vos performances. ARC suivra les références aux objets pour vous et synthétisera les méthodes de conservation / libération / libération automatique selon les règles normales. À cause de cela, ARC peut également publier des éléments dès qu'ils ne sont plus nécessaires, plutôt que de les jeter dans un pool de libération automatique uniquement pour des raisons de convention.
Certaines autres améliorations incluent la mise à zéro des références faibles, la copie automatique des blocs dans le tas, des accélérations à tous les niveaux (6x pour les pools de libération automatique!).
Une discussion plus détaillée sur la façon dont tout cela fonctionne se trouve dans les documents LLVM sur ARC.
la source
Cela varie considérablement de la collecte des ordures. Avez-vous vu les avertissements qui vous indiquent que des fuites d'objets peuvent se produire sur différentes lignes? Ces instructions vous indiquent même sur quelle ligne vous avez affecté l'objet. Cela a été pris un peu plus loin et peut désormais insérer
retain
/release
instructions aux emplacements appropriés, mieux que la plupart des programmeurs, presque 100% du temps. Parfois, il y a des exemples étranges d'objets retenus avec lesquels vous devez l'aider.la source
Très bien expliqué par la documentation du développeur Apple. Lire "Comment ARC fonctionne"
Connaître Diff. entre Garbage collection et ARC: Lisez ceci
la source
ARC est une fonction de compilation qui fournit une gestion automatique de la mémoire des objets.
Au lieu de devoir vous rappeler quand utiliser
retain, release
, etautorelease
ARC évalue les exigences de durée de vie de vos objets et insère automatiquement les appels de gestion de mémoire appropriés pour vous au moment de la compilation. Le compilateur génère également pour vous des méthodes de désallocation appropriées.Le compilateur insère les
retain/release
appels nécessaires au moment de la compilation, mais ces appels sont exécutés au moment de l'exécution, comme tout autre code.Le diagramme suivant vous permettra de mieux comprendre le fonctionnement de l'ARC.
Ceux qui sont nouveaux dans le développement iOS et n'ont pas d'expérience de travail sur l'objectif C. Veuillez consulter la documentation d'Apple pour le Guide de programmation de la gestion avancée de la mémoire pour une meilleure compréhension de la gestion de la mémoire.
la source