Whats up avec la mémoire statique en java?
Cette question est pour le langage java en particulier. Je comprends qu'il y est un statique de la portion de mémoire réservée pour tous de code statique.
Ma question est de savoir comment cela statique de la mémoire remplie? Est un objet statique mis en mémoire statique à l'importation, ou à la première référence? Aussi, faites de même la collecte des ordures règles s'appliquent à des objets statiques comme ils le font pour tous les autres objets?
public class Example{
public static SomeObject someO = new SomeObject();
}
/********************************/
//Is the static object put into static memory at this point?
import somepackage.Example;
public class MainApp{
public static void main( Sting args[] ){
//Or is the static object put into memory at first reference?
Example.someO.someMethod();
//Do the same garbage collection rules apply to a
// static object as they do all others?
Example.someO = null;
System.gc();
}
}
Vous devez vous connecter pour publier un commentaire.
Les importations ne sont pas en corrélation avec toutes les instructions dans le code compilé. Ils établissent des alias pour les utiliser au moment de la compilation seulement.
Il y a quelques réfléchissant méthodes qui permettent à la classe à charger, mais pas encore initialisé, mais dans la plupart des cas, vous pouvez supposer que chaque fois qu'une classe est référencé, il a été initialisé.
Membre statique initialiseurs statiques et les blocs sont exécutés comme s'ils étaient tous un initialiseur statique bloc dans l'ordre de code source.
Un objet référencé par une variable membre statique est fortement référencé, jusqu'à ce que la classe est déchargée. Normal
ClassLoader
jamais décharge de classe, mais ceux qui sont utilisés par les serveurs d'applications à faire dans de bonnes conditions. Cependant, il est délicat et a été la source de beaucoup de dur-à-diagnostiquer les fuites de mémoire—encore une autre raison de ne pas utiliser de variables globales.Comme un (tangentiel) en bonus, voici une question délicate à prendre en compte:
Qu'est ce que ce code d'impression? Essayez, et vous verrez qu'elle s'imprime "6". Il y a quelques choses à l'œuvre ici, et l'un est de l'ordre de l'initialisation statique. Le code est exécuté comme s'il avait été écrit comme ceci:
ClassLoader
jamais décharge de classe. Le système de chargeur de classe n'est pas normal, c'est une classe spéciale chargeur créé par le runtime. Je ne sais pas si c'est possible de le décharger, mais je sais que je ne l'ai jamais vu faire.OutOfMemoryError
est l'alternative. Bien sûr, les environnements comme un PCR ou serveur d'application généralement de créer de nombreux chargeurs de classe, et sont susceptibles d'être en mesure de jeter ces chargeurs et leurs classes. Je suis de plus parler d'une simple application autonome avec unmain()
méthode.C1
,C2
,C3
, etc peuvent être attachés à notre chargeur de classe. Donc siC1
a une instance statique C1V1 de typeC2
, puis C1V1 instance n'est pas attaché à C1 de la définition de la classe, mais attachés directement à notre chargeur de classe. De cette façon.............C1
. Point 2) concernant la "valeur de hachage peut changer" - On peut simplement résoudre ce par le traitement de la valeur de hachage comme un état statique et de l'application de la solution ci-dessus. En d'autres termes, la valeur de hachage est maintenue même lorsque la définition de la classe est supprimée de la mémoire.static
champs, pourrait être interprété comme “en réalité ne pas décharger, mais reconstructable de données”. À cet égard, certaines de ces choses ne se produisent aujourd'hui, par exemple, quand un “partage de données de classe” de l'archive est utilisé, il est mappé en mémoire dans le processus et, par conséquent, certaines parties peuvent obtenir de manière transparente supprimé de la mémoire physique et rechargé par le système d'exploitation. De plus, rarement utilisé le code peut obtenir deoptimized, la suppression du code compilé. Assez proche...Il n'est normalement pas une telle chose comme "statique" de la mémoire. La plupart des machines virtuelles ont la génération permanente de la tas (où les classes sont chargées), qui, normalement, ne sont pas des déchets collectés.
Les objets statiques sont alloués comme tout autre objet. Mais, s'ils vivent pour longtemps, ils seront déplacés entre les différentes générations dans le garbage collector. Mais ils ne se retrouveront pas dans permgenspace.
Si votre classe est maintenant sur cet objet de manière permanente, il ne sera levée que lorsque la machine virtuelle sorties.
Cette variable statique some0 est initialisé dès que votre classe est référencé dans votre code. Dans votre exemple, ce sera exécutée dans la première ligne de votre méthode principale.
Vous pouvez valider ce par la création d'un initialiseur statique bloc. Placez un point d'arrêt dans cette initialiseur de bloc et vous verrez, quand il sera appelé. Ou même plus de plus simple... de mettre un point d'arrêt dans le constructeur de SomeObject.
L'initialisation des variables statiques est couvert dans la Section 2.11 Les Initialiseurs Statiques de soleils JVM spec. La spécification ne définit pas la mise en œuvre de la collecte des Ordures, cependant j'imagine que la collecte des ordures règles pour les objets statiques varie en fonction de votre VM.
Il convient de noter que seul le pointeur (ou tout autre type primitif) est stocké dans la PermGenSpace (c'est le vrai nom de la zone où la statique des choses est stockée).
Si l'Objet référencé par le pointeur se trouve dans la normale tas, comme tout autre objet.
Si le champ statique est modifié pour faire référence à un autre objet, l'original de l'objet pointé par le champ statique est admissible pour le GC, comme tout autre objet.
Il pourrait également être libre, ed (même si c'est pas entaché de nullité) si la classe elle-même est déchargé et l'ensemble de l'objet graphique est de couper dans le tas. Bien sûr, si une classe peut être déchargé est un bon sujet pour une foule d'autres questions... 🙂