Question générale: Java a le tas et la pile locale. Pouvez-vous accéder à n'importe quel objet du tas?

StackOverflow https://stackoverflow.com/questions/289138

  •  08-07-2019
  •  | 
  •  

Question

Je regardais vraiment les différences entre le nombre de passes par valeur et la manière dont Java attribue les objets et ce que java fait pour placer des objets sur la pile.

Est-il possible d'accéder aux objets alloués sur le tas? Quels sont les mécanismes appliqués par Java pour garantir que la bonne méthode puisse accéder aux bonnes données du tas?

Il semble que si vous étiez astucieux et peut-être même manipuliez le bytecode java pendant l'exécution, vous pourriez peut-être manipuler des données à partir du tas quand vous n'êtes pas censé le faire?

Était-ce utile?

La solution

Il n'y a pas d'instruction dans le jeu d'instructions JVM qui donne un accès arbitraire au segment de mémoire. Par conséquent, la manipulation de code intermédiaire ne vous aidera pas ici.

La machine virtuelle Java dispose également d'un vérificateur. Il vérifie le code de chaque méthode (lors du chargement d'une classe) pour vérifier que la méthode n'essaie pas d'extraire plus de valeurs de la pile d'exécution que ce qu'elle lui avait imposé. Cela garantit qu’une méthode ne peut pas & voir; voir " les objets pointés par sa méthode d'appel.

Enfin, les variables locales sont stockées dans un tableau spécifique (appelé le "tableau de variables locales"). Là encore, le vérificateur s'assure que chaque instruction de lecture / écriture de / vers ce tableau spécifie un index inférieur à la taille du tableau. Notez que ces instructions JVM peuvent uniquement spécifier un index constant. Ils ne peuvent pas prendre une valeur calculée et l'utiliser comme index.

Donc, pour récapituler, la réponse est non.

Autres conseils

Tous les objets en Java sont situés sur le tas. Je ne suis pas tout à fait sûr de ce que vous entendez par "accéder aux objets du tas". Les seuls éléments stockés dans la pile sont la liste des fonctions appelées dans le contexte actuel, ainsi que leurs variables et paramètres locaux. Toutes les variables et tous les paramètres locaux sont des types primitifs ou des références.

Si vous allouez un objet à l'aide de new (qui est le seul moyen d'allouer des types non primitifs; oui, cela inclut les types de tableaux), l'objet est alloué sur le segment de mémoire et une référence à cet objet est stocké dans la pile ou dans le tas, selon que la référence est stockée dans une variable / paramètre local ou en tant que membre d'un autre objet.

Lorsqu'ils sont transmis en tant que paramètres à des fonctions, tous les objets sont passés par référence. Si la fonction modifie le paramètre, l'objet d'origine est également modifié. Identiquement, on pourrait également dire que les références d'objet sont passées par valeur - si vous modifiez un paramètre pour faire référence à un nouvel objet, il continuera à faire référence à cet objet pendant la durée de la fonction, mais l'objet d'origine qui a été transmis fera toujours référence à tout ce qui a été mentionné auparavant. Les types primitifs sont également passés par valeur.

En ce qui concerne les objets de la pile, ce n'est que la nouvelle machine virtuelle Java 6 de SUN (et peut-être d'autres) qui tentera d'optimiser le code octet en plaçant des objets sur la pile. En règle générale, tous les objets iront dans le tas. Pour référence, consultez: http://www.ibm.com/ developerworks / java / bibliothèque / j-jtp09275.html

La spécification JVM se trouve également à l'adresse http : //java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348 . La JVM protège son segment en ne vous donnant simplement pas les instructions nécessaires pour le corrompre. Des failles dans les implémentations de JVM peuvent entraîner une variation de votre kilométrage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top