Android : les Champs Statiques et les Fuites de Mémoire
J'ai été l'étude sur les meilleures pratiques pour prévenir le Contexte/l'Activité de la mémoire lors de la création de points de vue, et je n'arrive pas à trouver une réponse précise sur ce qui est ou n'est pas autorisé quand il s'agit de champs statiques dans les classes.
Disons que j'ai un code de ce formulaire:
public class MyOuterClass extends Activity{
private MyInnerClass;
MyInnerClass = (MyInnerClass) findViewById(<XML call here>);
MyInnerClass.myXInt = 3;
//onCreate(), onResume(), etc.
public static class MyInnerClass extends SurfaceView implements Runnable{
//Safe variables?
private static int myXInt, myYInt;
private static boolean myBoolean;
//Potentially safe?
private static Canvas myCanvas;
//Definitely bad.
private static Context myContext;
public MyInnerClass(Context context){
myContext = context; //This is bad.
}
}
}
Je suis un peu confus sur ce que la JVM fait estime le chargeur de classe pour MyInnerClass. Techniquement, puisque c'est une SurfaceView objet, il semble que les variables statiques doit toujours exister une fois que la demande a instancié MyInnerClass une seule fois (ce qui arrive lorsque la Vue est d'abord gonflé), puis d'y rester jusqu'à ce que l'application elle-même est terminée. Si c'est le cas, ce qui empêche les Bitmaps et les objets en Toile de rester ouvert et de remplir le tas?
La déclaration que j'ai jamais voir se répéter plus et plus, c'est que vous ne pouvez pas fuite de Contexte statique comme je l'ai montré dans le constructeur, mais il ne va jamais au-delà. Est-ce vraiment la seule chose que vous ne pouvez pas le faire?
Canvas
etc n'a pas besoin d'être static
. De cette façon, il serait, en effet, rester dans le tas pour toujoursSi c'est le cas, alors ce qui empêche les constantes (c-à - private static final int MY_CONSTANT), de la détention d'une classe qui étend la classe de l'activité (et de son contexte) ouvrir?
OriginalL'auteur SeaNick | 2012-08-10
Vous devez vous connecter pour publier un commentaire.
En Java/Android un
static
variable ou une constante ne sera pas nettoyée. Il reste simplement là, une fois la classe qui détient elle est chargée par un chargeur de classe. Le chargeur de classe est autant que je sache toujours le même pour toutes les classes à l'intérieur de votre application et ses le un qui a de la statique des références à toutes vos classes (par exempleMyInnerClass.class
). Depuis le chargeur de classes ne pas aller loin de vos classes ne faire que ce soit depuis qu'ils sont référencés & donc pas de garbage collector.Comme dans votre exemple
C'est en effet mauvais. Même si aucune référence à
SomeClass
existe (par exemple, laActivity
qui a montré personnalisé de votreSurfaceView
a fini) la référence statique pour lesContext
(et tous les autresstatic
variable /constante dansSomeClass
restera. Vous pouvez considérer tous de leur fuite, car il n'est pas possible de collecter les ordures quiContext
etc. Si vous avez régulièrement référence à une variable quelque chose, puis une fois l'instance qui contient cette variable n'a pas plus de références à l'ensemble de l'instance, y compris ses références à d'autres choses peuvent et doivent être des ordures collectées. Java permet même de gérer les références circulaires amende.Pour les constantes que vous voulez que cela se produise et il n'est généralement pas mauvais, puisque le montant de constantes et de la quantité de mémoire qu'ils occupent n'est pas grande. Aussi les constantes de ne pas (ne doit pas) faire référence à d'autres instances que prendre de grandes quantités de mémoire, comme
Context
ouBitmap
.D'ailleurs la possibilité de créer des fuites de mémoire à travers des variables statiques, vous pouvez également créer des problèmes si vous ne voulez pas avoir une seule chose pour toutes les instances en même temps. Par exemple, si vous enregistrez le
Bitmap
de votreSurfaceView
dans unstatic
variable que vous ne pouvez pas avoir deux images différentes. Même si les deuxSurfaceView
s ne sont pas affichés dans le même temps, vous pourriez rencontrer des problèmes puisque chaque nouvelle instance va probablement remplacer l'ancienne image et si vous allez vers les autresSurfaceView
vous à l'improviste montrer une image erronée. Je suis presque sûr que vous ne voulez pas utiliserstatic
ici.Le fait que l'intérieur de votre classe est un
static class
ne signifie pas que vous devez utiliser des variables statiques, il signifie simplement qu'il se comporte plus comme unstatic
méthode, car il ne peut pas utiliser les variables d'instance (ceux qui ne sont passtatic
) dans votre classe.Pour éviter les fuites de mémoire que vous simplement ne devrait pas utiliser de variables statiques. Il n'est pas nécessaire de les utiliser à moins que vous n'spéciales (par exemple, le comptage des instances d'une classe). Les constantes sont beaux.
Vous n'avez pas besoin d'avoir quelque chose de statique à le maintenir en vie et de le réutiliser. Il existe aussi longtemps que vous avez une référence à elle. Et à l'aide de statique sera généralement conduire à plus de consommation de mémoire si vous oubliez de
null
tous vos références statiques de façon appropriée. + Afficher les instances généralement être recréé si vous faites pivoter l'écran par exempleJe garde l'orientation de l'écran verrouillé, mais c'est un très bon point. Merci encore!
bonne explication, j'ai été en utilisant weakReference le contexte pour éviter la fuite de mémoire
OriginalL'auteur zapl
Cet article parle de la mutable champs statiques: http://javabook.compuware.com/content/memory/problem-patterns/memory-leaks.aspx. Fondamentalement, les éviter et utiliser des constantes à la place.
OriginalL'auteur IgorGanapolsky