7
votes

Taille de la mémoire des classes dans l'objectif-c

Je suis intéressé à connaître la taille de la mémoire, affectant des objets de l'objectif-C.

Par exemple:

est [nstring stringwithstring: @ "2"] plus gros que [Numéro de nsnumberwithint: 2] ou pas?

et combien plus grand est [nsnumber Numberwithint: 2] que int num = 2 ?

Y a-t-il une documentation d'Apple sur cette question? Je pense que cette information est très importante pour l'optimisation de la mémoire.


1 commentaires

Bienvenue dans le débordement de pile. Veuillez mettre des efforts dans le format de votre question, par exemple. Utilisez le formatage du code et les paragraphes pour une meilleure lisibilité.


4 Réponses :



4
votes

Il n'y a pas une chose comme un nstring ou un nsnumber , la logique d'entre eux est réellement mise en œuvre dans plusieurs classes différentes, chacune d'entre elles ayant plus ou moins leur propre empreinte mémoire. Donc, il est donc impossible de dire à quel point une classe Poids avant l'exécution (vous pouvez toutefois demander à l'OBJC Runtime à ce sujet). Cela dit, une autre chose est que [nsnumber Numberwithint: 2] retournera probablement une instance singleton de nsnumber (Afair chaque entiers jusqu'à 12 est mis en cache), donc vous ne pouvez pas 't ajoutez vraiment quelque chose à votre empreinte mémoire.

Et à côté de tout ce que cela, deviendra le moyen d'optimiser votre mémoire est la mauvaise manière! Si un objet pèse 64 octets plus que l'autre, alors quoi? 64 octets ne sont rien, même sur un iPhone! Vous vous retrouverez avec des problèmes de mémoire plus importants où vous pouvez réellement optimiser, par exemple. par paresseux charger vos affaires ou autre chose. Mais ces problèmes sont trouvés lors des tests avec des instruments et non à l'avance lorsque vous écrivez votre code! (Vous seriez surpris de combien de fois une simple "optimisation" faite même avant que le test fonctionne soit sans effet, soit même un impact pire performance!)


2 commentaires

+1: C'est (normalement) inutile d'optimiser l'empreinte mémoire d'une application. Sauf si vous rencontrez quelque chose comme ça: Cocoawithlove.com/2010/ 08 / alternative-objectif-c-objet.htm l


NIT: Vous dites "renverra probablement une instance singleton de nsnumber ". Mais ce n'est pas ce qu'est un singleton. Un singleton est la seule instance dans toute la classe . Vous ne pouvez pas avoir plusieurs singletons instanciés. Donc, ce qui est retourné est un objet unique , mais ce n'est pas un singleton.



14
votes

La documentation exacte n'est pas disponible, au meilleur de ma connaissance. Nstring et (IIRC) Nsnumber sont implémentés comme clusters de classe , c'est-à-dire que vous demandez un nouvel objet, vous pourrait obtenir un objet de la sous-classe non documentée.

Cela signifie également que les choses peuvent changer sans avertissement lorsque votre programme s'exécute sur une version OS différente, ne comptez donc pas sur des chiffres exacts.

Maintenant, essayons une estimation approximative. Les entiers sont 4 octets sur toutes les plateformes Apple actuelles. Les pointeurs sont 4 octets sur iOS.

Les objets sont alloués sur le tas; Au niveau le plus bas, l'allocation de tas est effectuée par malloc . Je supposerai que la mise en œuvre de MALLOC d'IOS est dérivée de celle utilisée sur Mac OS - Regardez ici pour certains détails: http://cocoawithlove.com/2010/05/look-at-how-malloc-works-on-mac.html

Le point le plus important est que l'allocation quantique pour les petits objets est de 16 octets, c'est-à-dire que les petits objets utiliseront un multiple de 16 octets.

Chaque objet Objective-C contient un pointeur à sa classe.

Donc, pour un nombre de nsnumber contenant une INT J'aurais estimé 4 octets pour votre pointeur, plus 16 octets pour l'objet (composé d'un pointeur de classe de 4 octets et - je suppose - un AT de quatre octets, plus 8 octets de l'espace perdu).

Pour un Nstring, il existe différentes sous-classes en béton pour différentes situations. Un littéral de chaîne @ "2" pointera sur un objet littéral à chaîne alloué statiquement attribué, une chaîne créée au moment de l'exécution aura probablement une représentation différente. En général, je suppose que 4 octets (votre pointeur) + 16 octets (l'objet Nstring) + nombre de caractères * 2 (Tailleof (Unichalar)) arrondi aux multiples de 16.

résumer, je estimation que nsnumbers nécessite environ cinq fois plus de mémoire que int s. Je estime en outre que le même numéro représenté comme un Nstring prend environ 10 fois plus de mémoire que d'un int . .

Notez également que l'allocation d'objets de l'objectif-C est beaucoup plus lentement que de définir une variable locale de type INT. Cependant, vous devez également vous rappeler que cela ne comportera souvent pas et que l'optimisation prématurée est la racine de tout le mal .


0 commentaires

2
votes

Dans le cas de Nsnumber et Nstring

NSLog(@"size was %ld", class_getInstanceSize([NSNumber class]));
NSLog(@"size was %ld", class_getInstanceSize([NSString class]));


0 commentaires