7
votes

A quoi ressemble Java en mémoire

Je suis nouveau à Java et j'apprends toujours. J'ai eu la tête autour des cours intérieurs et anonymes. Maintenant, j'ai une question technique sur la façon dont Java ressemble à la mémoire, lors de l'allocation d'objets, de définir des classes, etc.

Comme à quoi ressemble la mémoire quand j'ai un champ qui est un objet qui est défini dans une classe extérieure vs une classe intérieure. Les classes statiques sont-elles différentes que non statiques?

J'ai juste besoin d'une référence visuelle.

Merci gars


1 commentaires

Le "Comment" est un détail de mise en œuvre, non défini spécifique. Cela dit, ce livre ne vous dit pas comment une mise en œuvre de Java le fait réellement, mais cela vous dit comment une machine virtuelle de type Java pourrait le faire: www1.idc.ac.il/tecs


6 Réponses :


3
votes

Les détails sont dans la mise en œuvre (pas la spécification). Cependant, les implémentations suivent généralement un modèle très simple. La majeure partie de la mise en page de la mémoire en Java est très simple et directe. Ma terminologie peut ne pas correspondre à la terminologie Java, car je ne fais pas beaucoup de programmation Java.

En général, un objet commence par un pointeur à sa table de table, puis dispose d'un tas de champs qui suivent. Les champs sont des types primitifs (int / bool / float) ou des pointeurs vers des objets. C'est pour les objets. (Les classes sont également des objets.) Les pointeurs nul sont comme c, ils sont invalides, pas comme Python, où aucun n'est un objet.

Dans une classe intérieure, il existe un champ très masqué qui pointe sur une instance de la classe extérieure. C'est ainsi que les classes internes accèdent aux données de la classe extérieure. Les classes anonymes fonctionnent de la même manière. Les méthodes statiques ne sont que des méthodes sur la classe au lieu de méthodes sur l'instance.

La table équipée est où toute la magie se produit. Chaque classe a sa propre table de distribution partagée entre tous les objets. La tablette dispose d'informations sur la classe telles que la taille de ses instances et la manière dont les champs sont aménagés. Ces informations sont utilisées par le collecteur des ordures. La table équipée présente également des pointeurs à toutes les méthodes que la classe implémente. Lorsque vous appelez une méthode, l'exécution prend d'abord le pointeur TTBAble de l'objet, puis saisit le pointeur de la méthode hors de la table de commande, puis appelle la méthode et transmet l'objet à la méthode sous forme de paramètre implicite. Il est similaire à C ++, mais beaucoup plus simple à mettre en œuvre. Le processus peut être ignoré si la méthode ou la classe est "finale".

Je sais que Java n'a pas vraiment de "pointeurs", il a des "poignées symboliques" ou somesuch, mais les implémentations communes utilisent juste des pointeurs anciens unis.


0 commentaires

1
votes

comme à quoi ressemble la mémoire quand je avoir un champ qui est un objet qui est défini dans une classe extérieure vs un classe intérieure. Les classes statiques sont-elles regardées différent de non statique?

Une instance de classe interne (ou anonyme) non statique aura une référence à l'instance de classe extérieure utilisée pour l'instancier. C'est ce qui permet à une méthode de la classe interne de faire référence aux membres de niveau d'instance déclaré dans la classe jointe. Normalement, cette référence est transmise à la classe interne sous forme de paramètre supplémentaire caché dans le constructeur. Mais si vous utilisez la réflexion pour créer une instance de classe interne, vous devez fournir ce paramètre supplémentaire explicitement.

(Notez qu'un mécanisme différent est utilisé lorsqu'une classe anonyme utilise les locaux / paramètres dans le cadre de la méthode qui l'instancite ...)

Si vous avez besoin de plus de détails, vous pouvez utiliser Javap pour démonter les bytecodes de quelques classes d'exemple simples.

J'ai juste besoin d'une référence visuelle.

Désolé, je ne fais pas de jolies images: -)


2 commentaires

Ok j'ai trouvé une bonne ressource avec des diagrammes :) Artima.com/Inidejvm/ed2/jvm.html


@PP - J'ai parcouru à travers cette ressource et je ne pouvais voir aucune image qui a répondu à cette question particulière sur les classes intérieures. Vous devrez peut-être acheter une copie papier du livre ...



3
votes

Bienvenue dans le monde de Java. Contrairement à la langue C où la construction de la langue et la représentation de la mémoire cartes sont à peu près un à une, Java est légèrement plus compliquée.

Tout d'abord, lorsque les gens parlent de Java, cela pourrait signifier deux choses: Java-The-Language et Java-the-Platform. Ici, je veux dire Java pour être le langage de programmation Java. Le code écrit en Java est d'abord compilé en byTecode, code machine pour la machine virtuelle Java. Si vous êtes intéressé par les détails de la langue Java, voici Spécification de la langue Java < / a>. Et pour JVM, il y a Spécification de la machine virtuelle Java .

Que ressemble à la mémoire lorsque j'ai un champ qui est un objet qui est défini dans une classe extérieure vs une classe interne.

Je vais interpréter cela pour être à quoi ressemble la mise en page de la mémoire dans la machine virtuelle Java, car la mise en page physique est à la hauteur de la mise en œuvre de la JVM. Pour cela, je skimmed Structure de la machine virtuelle Java .

Comme la langue Java, la machine virtuelle Java fonctionne sur deux types de types: types primitifs et types de référence . Il existe, en conséquence, deux types de valeurs pouvant être stockées dans des variables, passées comme des arguments, renvoyées par des méthodes et fonctionnent sur: valeurs primitives et valeurs de référence . .

La machine virtuelle Java espère que presque toutes les vérifications de type se font lors de la compilation, pas par la machine virtuelle Java elle-même. En particulier, des données ne doivent pas nécessairement être étiquetées ou autrement être inspectables pour déterminer les types.

....

Une référence à un objet est considérée comme ayant Java Virtual machine de type référence . Valeurs de type référence peut être considérée comme des pointeurs d'objets.

La réponse semble-t-elle, c'est que les deux champs ressembleraient exactement à la même chose: référence .


0 commentaires


0
votes

Une classe statique (imbriquée) fonctionne exactement de la même manière qu'une classe de niveau supérieur. La seule différence est que son nom a un autre nom de classe le préfixant. (Si vous regardez les fichiers Compilés .Class, vous verrez réellement que vous obtiendrez quelque chose comme «OUTER $ NEST.CLASS» pour une classe nommée nichée imbriquée dans une classe nommée externe.)

Une classe intérieure a un Champ caché qui est une référence à l'instance contenant de sa classe externe. Lorsque vous écrivez: xxx

C'est comme si vous aviez écrit: xxx

nom de ce champ caché ( que j'ai appelé "extérieur" ici) est caché à vous, bien que vous puissiez vous référer à celui-ci en disant extérieur.C'est à l'intérieur du Classe intérieure (où externe est le nom de votre classe extérieure, bien sûr). De même, remarquez que lorsqu'une méthode dans la classe interne fait référence à quelque chose dans la classe extérieure, cette référence est en fait via celle cachée Référence à la classe extérieure.

Il y a quelques complications supplémentaires en ce qui concerne la manière dont le contrôle d'accès (par exemple: privé) fonctionne avec des classes imbriquées / intérieures, mais cela n'affecte pas vraiment la "mémoire" qui vous demandez.


0 commentaires

0
votes
class I$inner {

  // Field descriptor #6 LI;
  final synthetic I this$0;

  // Method descriptor #8 (LI;)V
  // Stack: 2, Locals: 2
  I$inner(I arg0);
     0  aload_0 [this]
     1  aload_1
     2  putfield I$inner.this$0 : I [10]
     5  aload_0 [this]
     6  invokespecial java.lang.Object() [12]
     9  return
      Line numbers:
        [pc: 0, line: 3]
      Local variable table:
        [pc: 0, pc: 10] local: this index: 0 type: I.inner

  // Method descriptor #14 ()V
  // Stack: 0, Locals: 1
  public void ctor();
    0  return
      Line numbers:
        [pc: 0, line: 4]
      Local variable table:
        [pc: 0, pc: 1] local: this index: 0 type: I.inner
}

0 commentaires