2010-03-19 3 views
14

Je sais que cela peut être une question stupide, mais mon expérience est plus en C++ et de gérer ma propre mémoire. Je suis actuellement en train de réduire chaque allocation que je peux de l'un de mes jeux pour essayer de réduire la fréquence de ramassage des ordures et le "retard" perçu, donc pour chaque variable que je crée qui est un objet (String et Rect par exemple) Je m'assure que je le crée avant main dans mon constructeur et ne crée pas des variables temporaires dans des fonctions de ligne simples ... (j'espère que cela a du sens)Les types primitifs sont-ils collectés dans Android?

De toute façon je travaillais encore plus ce soir et j'ai réalisé que je peux me tromper complètement sur mes suppositions sur le garbage collection et les types primitifs (int, boolean, float) sont ces variables de type primitives que je crée dans une fonction de 10 lignes qui s'appelle 20 fois par seconde à mon problème de ramassage des ordures?

Donc il y a un an toutes les quelques secondes que je verrais un message dans logcat comme

GC 4010 objets/libérés 484064 octets dans 101ms

Maintenant, je vois ce message tous les 15-90 secondes ou plus ...

Donc, pour reformuler ma question: Les types primitifs (int, float, boolean, etc.) sont-ils inclus lorsque vous voyez ce message?

Répondre

24

types primitifs ne sont pas des objets, de sorte qu'ils ne causent pas de collecte des ordures. Cependant, vous devez être très prudent car en raison de la boxe, un type primitif peut facilement devenir un objet sans que vous le fassiez explicitement. Par exemple, si vous voulez un HashMap <> de clés entières, vous utiliserez HashMap. Notez que parce que "int" n'est pas un objet, il ne peut pas être utilisé dans un conteneur. Entier est une version d'objet d'un int primitif. Lorsque vous écrivez du code comme celui-ci, un objet entier sera automatiquement créé pour vous:

HashMap<Integer, Object> map = new HashMap<Integer, Object>(); 
int someNum = 12345; // no object created. 
map.put(someNum, null); // Integer object created. 

Notez que se produira si vous n'utilisez pas génériques, mais encore plus caché exactement la même chose:

HashMap map = new HashMap(); 
int someNum = 12345; // no object created. 
map.put(someNum, null); // Integer object created. 

Pour cette situation particulière, vous pouvez utiliser la classe SparseArray d'Android, qui est un conteneur de clés entières primitives.

6

Il semble que la réponse est non. Il semble que les primitives soient placées sur la pile en Java et non dans le tas et que seuls les objets soient collectés. J'ai trouvé beaucoup de courtes références à ce sujet, consultez Wikipedia. Pour une lecture un peu plus lourde, voir un document sur une implémentation de garbage collection JVM qui explique un peu plus clairement que les primitives sont stockées dans des emplacements de mémoire séparés physiquement afin qu'ils ne soient pas inclus par erreur dans le garbage collection here. Si vous avez envie d'écrémer, la page 4 est celle où cela est expliqué le plus directement.

ici sont sujets spécifiques android indiquant le gc only scans pointers et comment it checks that

+0

Android n'exécute pas de JVM basée sur une pile standard, mais possède sa propre machine virtuelle basée sur le registre. – mikerobi

2

[Note: Je n'ai pas encore tous les privilèges de commentaire, donc j'ajoute ceci comme réponse séparée.]

On dirait que les primitives sont mis sur la pile en Java et non dans le tas et que des objets sont des ordures collectés.

Ce n'est pas tout à fait exact. Les primitives peuvent être conservées dans des variables locales et aussi dans les champs statiques ou d'instance des classes. Dans le dernier cas, ils sont en effet stockés sur le tas, mais ils ne possèdent pas de "vie" et ne sont pas séparés de l'objet dans lequel ils sont contenus.

Android ne fonctionne pas une norme basée sur la pile JVM , il a son propre registre base VM.

Ceci est une déclaration vraie, mais c'est aussi un peu trompeur et à côté du point de la question d'origine. En effet, lorsqu'une méthode en appelle une autre (et ainsi de suite), les trames d'activation de ces méthodes sont stockées sur une pile dans l'implémentation de Dalvik. La différence est que, en regardant une trame d'activation de manière isolée, les trames d'activation Dalvik ne contiennent pas dans une pile de taille variable. À cet égard, la façon dont Dalvik organise les cadres d'activation est plus proche de la manière dont ils sont traités pour les langages C traditionnels (tels que C ou C++).

+0

attendre jusqu'à ce qu'ils obtiennent un N.P.E. en raison d'aucun constructeur trivial par défaut sur un auto dans un appel de méthode, puis essayez de le poursuivre en utilisant l'effacement de type comme seule indication - la question de base d'ope concerne la création d'objets cachés & G.C. ce qui est difficile à gérer pour un paradigme de programmation de style C où l'on peut accomplir ce que D fait avec ceci ... bien que la seule approche efficace consiste à utiliser un mot-clé synchronisé et à réutiliser des obj ref (ce qui va devenir beaucoup de hurlements de la part des traditionalistes établis de Java) alors ce que l'OP doit faire, c'est lire Hans-J. Les commentaires de Boehm dans gc.h –

Questions connexes