28 votes

Un objet tableau contient-il explicitement les index?

Depuis le jour un de l'apprentissage de Java j'ai été dit par les différents sites internet, et de nombreux enseignants dont les tableaux sont consécutifs emplacements de mémoire qui peut stocker le nombre spécifié de données de même type.

Depuis un tableau est un objet et les références de l'objet sont stockés sur la pile, et la réalité des objets de vivre dans le tas, les références de l'objet point d'objets réels.

Mais quand je suis venu à travers des exemples de la façon dont les tableaux sont créés dans la mémoire, ils montrent toujours quelque chose comme ceci:

(Dans laquelle une référence à un tableau d'objet est stocké sur la pile et que les points de référence de l'objet réel dans le tas, où il y a aussi explicite des indices pointant à certains emplacements de mémoire)

Internal working of objects taught by various websites and teachers

Mais récemment je suis tombé sur en ligne les notes de Java dans lequel ils affirment que des baies explicite les index ne sont pas spécifiés dans la mémoire. Le compilateur sait exactement où aller en regardant la condition numéro d'index de tableau en cours d'exécution.

Juste comme ça:

Enter image description here

Après la lecture des notes, j'ai aussi cherché sur Google au sujet de cette affaire, mais le contenu sur cette question ont été soit très ambigu ou inexistante.

J'ai besoin de plus de précisions sur cette question. Sont objet de tableau d'index figurant explicitement dans la mémoire ou pas? Si non, alors comment Java gérer les commandes d'aller à un endroit particulier dans un tableau en cours d'exécution?

14voto

Maroun Maroun Points 31217

En Java, les tableaux sont des objets. Voir la JLS - Chapitre 10. Tableaux:

Dans le langage de programmation Java, les tableaux sont des objets (§4.3.1), sont créées dynamiquement, et peuvent être affectés à des variables de type Objet (§4.3.2). Toutes les méthodes de la classe Object peut être invoquée sur un tableau.

Si vous regardez 10.7. Les Membres du groupe chapitre, vous verrez que l'index n'est pas une partie de la matrice de membre:

Les membres d'un type tableau sont les suivantes:

L' public final domaine length, qui contient le nombre de composants de la matrice. la longueur peut être positif ou nul.

  • L' public méthode clone, ce qui remplace la méthode du même nom dans la classe Object et le jette pas vérifié exceptions. Le type de retour de la méthode clone d'un tableau de type T[] est T[].

  • Tous les membres hérités de la classe Object; la seule méthode de l'Objet qui n'est pas héréditaire, c'est sa méthode clone.

Puisque la taille de chaque type est connu, vous pouvez facilement déterminer l'emplacement de chaque composant de la matrice, compte tenu de la première.

La complexité de l'accès à un élément de O(1), car elle a seulement besoin de calculer le décalage d'adresse. Il est important de mentionner que ce comportement n'est pas assumée pour tous les langages de programmation.

14voto

Boann Points 11904

Ne un objet array explicitement contiennent les index?

Réponse courte: Non.

Plus de réponse: Généralement pas, mais il pourrait théoriquement faire.

Réponse complète:

Ni le Langage Java Spécification ou de la Machine Virtuelle Java Spécification ne fait aucune garantie quant à la façon dont les tableaux sont mis en œuvre en interne. Tout ce qu'il faut, c'est que les éléments du tableau sont accessibles que par un int numéro d'index ayant une valeur de 0 de length-1. Comment une mise en œuvre récupère effectivement ou stocke les valeurs de ces éléments indexés est un détail privé à la mise en œuvre.

Parfaitement conforme à la JVM peut utiliser une table de hachage pour mettre en œuvre des tableaux. Dans ce cas, les éléments non consécutifs, dispersés autour de la mémoire, et il serait nécessaire d'enregistrer les indices des éléments, à savoir ce qu'ils sont. Ou il pourrait envoyer des messages à un homme sur la lune qui écrit le tableau de valeurs vers le bas sur étiquetés morceaux de papier et les stocke dans des tas de petites armoires. Je ne vois pas pourquoi une JVM aurait envie de faire ces choses, mais il pourrait l'être.

Ce qui va se passer dans la pratique? Typique de la JVM va affecter le stockage pour les éléments du tableau comme un plat, espace contigu de mémoire. La localisation d'un élément particulier est trivial: multipliez la taille de mémoire fixe de chaque élément par l'index de l'voulu élément et l'ajouter à la mémoire de l'adresse de début du tableau: (index * elementSize) + startOfArray. Cela signifie que la matrice de stockage se compose de rien de mais des premières valeurs d'élément, consécutivement, commandé par l'index. Il n'y a pas de but à la aussi le stockage de la valeur de l'indice à chaque élément, parce que l'élément de l'adresse dans la mémoire implique son index, et vice-versa. Cependant, je ne pense pas que le diagramme de vous montrer était en train de dire que c'explicitement stockées à l'index. Le schéma est simplement étiqueter les éléments sur le diagramme de sorte que vous savez ce qu'ils sont.

La technique de l'utilisation de contiguë de stockage et de calcul de l'adresse d'un élément de la formule est simple et extrêmement rapide. Il a aussi très peu de surcharge de la mémoire, en supposant que les programmes de l'allocation de leurs tableaux seulement aussi grand que ils ont vraiment besoin. Programmes dépendent et d'en attendre de particulier les caractéristiques de performance de tableaux, donc une machine qui a fait quelque chose de bizarre avec la matrice de stockage serait probablement effectuer de mal et d'être impopulaires. De manière pratique, les machines virtuelles seront contraints de mettre en œuvre stockage contigu, ou quelque chose qui effectue la même façon.

Je pense seulement un couple de variations sur ce régime qui ne serait jamais utile:

  1. Pile ou l'affectation de registre-des tableaux alloués: au Cours de l'optimisation, une JVM peut déterminer par le biais d' échapper à l'analyse d'un tableau est utilisé uniquement à l'intérieur d'une méthode, et si le tableau est également une petite taille fixe, alors il serait un candidat idéal pour objet d'être affectées directement sur la pile, le calcul de l'adresse d'éléments par rapport au pointeur de pile. Si le tableau est extrêmement petit (de taille fixe de peut-être jusqu'à 4 éléments), une JVM peut même aller plus loin et de stocker les éléments directement dans les registres du CPU, avec tous les éléments accède déroulé & codé en dur.

  2. Paniers boolean tableaux: Le plus petit directement adressable unité de mémoire sur un ordinateur est généralement un octet de 8 bits. Cela signifie que si une JVM utilise un octet pour chaque élément booléen, alors une valeur booléenne tableaux des déchets 7 de chaque 8 bits. Elle serait d'utiliser seulement 1 bit par élément si booléens ont été emballés ensemble dans la mémoire. Ce conditionnement n'est pas fait en général à cause de l'extraction de bits des octets est plus lent, et il nécessite une attention particulière pour être sûr de multithreading. Cependant, paniers boolean tableaux pourrait tout à fait logique dans certains contrainte de mémoire embarquée.

Pourtant, aucune de ces variations exige de chaque élément pour stocker son propre index.

Je veux adresser quelques autres détails que vous avez mentionné:

les tableaux store le nombre spécifié de données de même type

Correct.

Le fait que tout un éventail d'éléments sont du même type est important car cela signifie que tous les éléments sont de la même taille en mémoire. C'est ce qui permet d'éléments à être situé en multipliant simplement par leur taille commune.

C'est toujours techniquement vrai si le type d'élément de tableau est un type de référence. Bien que dans ce cas, la valeur de chaque élément n'est pas l'objet lui-même (qui peut être de taille variable), mais seulement une adresse qui renvoie à un objet. Aussi, dans ce cas, la réelle de l'exécution type d'objets visés par chaque élément du tableau pourrait être une sous-classe du type d'élément. E. g.,

Object[] a = new Object[4]; // array whose element type is Object
// element 0 is a reference to a String (which is a subclass of Object)
a[0] = "foo";

// element 1 is a reference to a Double (which is a subclass of Object)
a[1] = 123.45;

// element 2 is the value null (no object! although null is still assignable to Object type)
a[2] = null;

// element 3 is a reference to another array (all arrays classes are subclasses of Object)
a[3] = new int[] { 2, 3, 5, 7, 11 };

les tableaux sont consécutifs emplacements de mémoire

Comme discuté ci-dessus, ce n'est pas vrai, bien qu'il est presque certainement vrai dans la pratique.

Pour aller plus loin, notez que bien que la JVM peut allouer un espace contigu de mémoire du système d'exploitation, cela ne veut pas dire qu'il finit par être contigus dans la RAM physique. Le système d'exploitation peut donner des programmes d'un espace d'adressage virtuel qui se comporte comme si d'un seul tenant, mais les pages de la mémoire dispersés dans divers endroits, y compris la RAM physique, les fichiers de swap sur le disque, ou régénéré selon le besoin, si leur contenu est connu pour être actuellement vide. Au point même que des pages de l'espace de mémoire virtuelle sont des résidents de la RAM physique, ils pourraient être disposés de RAM physique dans un ordre arbitraire, avec des tables de pages qui définissent la cartographie de l'virtuelles et les adresses physiques. Et même si l'OS pense que c'est de traiter avec les "RAM physique", il pourrait toujours être en cours d'exécution dans un émulateur. Il peut y avoir des couches sur des couches sur des couches, est de mon point de vue, et aller au fond d'eux tous pour savoir ce qui se passe réellement prend du temps!

Une partie de l'objet de spécifications langage de programmation est de séparer le comportement apparent de la mise en œuvre de détails. Lors de la programmation, vous pouvez souvent programme à la spécification seul, libre de se soucier de comment ça se passe en interne. La mise en œuvre des détails pertinents toutefois, lorsque vous avez besoin de traiter avec le monde réel, les contraintes de la vitesse limitée et de la mémoire.

Depuis un tableau est un objet et les références de l'objet sont stockés sur la pile, et la réalité des objets de vivre dans le tas, les références de l'objet point d'objets réels

C'est correct, sauf ce que vous avez dit à propos de la pile. Les références de l'objet peuvent être stockées sur la pile (comme des variables locales), mais ils peuvent également être stockés en tant que champs statiques ou des champs d'instance, ou comme des éléments d'un tableau comme on le voit dans l'exemple ci-dessus.

Aussi, comme je l'ai mentionné plus tôt, intelligent implémentations peuvent parfois allouer des objets directement sur la pile ou dans les registres du CPU comme une optimisation, mais cela n'a aucune incidence sur votre programme apparente de problème, seulement de ses performances.

Le compilateur sait exactement où aller en regardant la condition numéro d'index de tableau en cours d'exécution.

En Java, il n'est pas le compilateur qui fait cela, mais la machine virtuelle. Les tableaux sont une caractéristique de la JVM elle-même, de sorte que le compilateur peut traduire votre code source qui utilise des tableaux de simplement bytecode qui utilise des tableaux. Puis c'est la JVM du travail pour décider de la façon de mettre en œuvre des tableaux, et le compilateur ne sait ni se soucie de la façon dont ils travaillent.

10voto

Le tableau, comme vous dites, ne stocker des objets de même type. Chaque type dispose de la taille, en octets. Par exemple, dans un int[] chaque élément s'occuper de 4 octets, chaque byte en byte[] occupera 1 octet, chaque Object en Object[] occupera 1 mot (parce que c'est vraiment un pointeur sur le tas), etc.

La chose importante est que chaque type a une taille et chaque tableau a un type.

Puis, nous arrivons au problème de la cartographie d'un index pour une position de mémoire lors de l'exécution. C'est en fait très facile parce que vous savez où le tableau commence et, compte tenu de l'éventail du type, vous savez la taille de chaque élément.

Si votre tableau commence à mémoire de position de N vous pouvez utiliser l'index donné que je et la taille de l'élément S à calculer que la mémoire que vous cherchez sera à la mémoire de l'adresse N + (S * I).

C'est la façon dont Java trouve des positions de mémoire pour les index au moment de l'exécution sans avoir à les stocker.

7voto

Thomas Kläger Points 1029

Sur votre première image, arr[0] à arr[4] ne sont pas des références aux éléments du tableau. Ce ne sont que des étiquettes illustratives pour l'emplacement.

7voto

Viktor Toth Points 437

Vos deux diagrammes sont, à l'exception des labels qui sont strictement réservés à la consommation humaine, soit l'équivalent et identiques.

C'est-à-dire que dans le premier diagramme, les étiquettes arr[0], arr[1], etc., ne font pas partie de la matrice. Ils sont là, simplement à titre indicatif, en indiquant comment les éléments du tableau sont disposés en mémoire.

Ce qu'il vous a été dit, à savoir que les tableaux sont stockés dans des endroits contigus en mémoire (au moins dans la mesure où les adresses virtuelles sont concernés; sur du matériel moderne, des architectures, cela n'a pas besoin de carte en contigus adresses physiques) et les éléments du tableau sont situés en fonction de leur taille et de l'index, est correcte. (Au moins dans... eh bien, c'est certainement correct en C/C++. Il est certainement correctes dans la plupart, si pas tous, les implémentations Java. Mais il est probablement incorrect dans des langues qui permettent de matrices creuses ou des tableaux qui peuvent augmenter ou de réduire de façon dynamique.)

Le fait que la matrice de référence est créé dans la pile alors que les données du tableau sont placés sur le tas est une mise en œuvre spécifique de détail. Les compilateurs Java compiler directement en code machine peut mettre en œuvre de la matrice de stockage différemment, en prenant en compte les caractéristiques spécifiques de la cible de la plateforme matérielle. En fait, un savant compilateur peut, par exemple, de petits tableaux dans la pile, dans leur intégralité, et d'utiliser le tas seulement pour les grandes baies, afin de réduire la nécessité pour la collecte des ordures, ce qui peut influer sur les performances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X