2008-11-14 13 views
14

Je regardais vraiment les différences entre la valeur de passage et la façon dont Java alloue des objets et ce que fait Java pour placer des objets sur la pile.Question générale: Java a le tas et la pile locale. Pouvez-vous accéder à n'importe quel objet du tas?

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

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

+1

Bonne question - J'aimerais en savoir plus sur java; une bonne réponse à ceci sera un début à mon éveil :) –

Répondre

17

Il n'y a aucune instruction dans le jeu d'instructions JVM qui donne un accès arbitraire au tas. Par conséquent, la manipulation bytecode ne vous aidera pas ici.

La JVM 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 y a poussé. Cela garantit qu'une méthode ne peut pas "voir" les objets pointés par sa méthode d'appel. Enfin, les variables locales sont stockées dans un tableau par méthode (connu sous le nom de «tableau de variables locales»). Encore une fois, 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 un index.

Pour résumer, la réponse est non

+0

Je viens de revenir à cela. Donc, fondamentalement, la structure de Java et la collecte des ordures similaires, les langages basés sur les piles, sont tels que vous ne pouvez pas accéder arbitrairement à une partie du tas lorsque vous n'avez pas accès à cela. –

9

Tous les objets Java se trouvent sur le tas. Je ne suis pas sûr de ce que vous entendez par "accéder aux objets du tas". Les seules choses stockées sur la pile sont la liste des fonctions appelées dans le contexte courant et leurs variables et paramètres locaux. Toutes les variables et paramètres locaux sont soit des types primitifs, soit des références.

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

Passés en tant que paramètres de fonctions, tous les objets sont transmis par référence - si la fonction modifie le paramètre, l'objet d'origine est également modifié. De même, on pourrait dire que les références d'objets sont passées par valeur - si vous changez un paramètre pour faire référence à un nouvel objet, il continuera à se référer à cet objet pour la durée de la fonction, mais l'objet original passé se référera toujours à tout ce qu'il a mentionné avant. Les types primitifs sont également transmis par valeur.

+0

Il y a d'autres manières d'allouer de nouveaux objets (clone, Class.newInstance(), désérialisation), mais elles finissent toutes sur le tas. –

+4

L'explication "on pourrait aussi dire que les références d'objets sont passées par valeur" est la seule précise.Dire que les objets sont passés par référence est inexact. Fondamentalement Java a seulement valeur de passe, comme C. –

4

En ce qui concerne les objets sur la pile, il est seulement le nouveau Java 6 VM de SUN (et peut-être quelques autres) qui vont essayer d'optimiser le code octet en mettant sur des objets la pile. Typiquement, tous les objets vont dans le tas. Pour référence, consultez: http://www.ibm.com/developerworks/java/library/j-jtp09275.html

La spécification JVM est également à http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348. La JVM protège son tas en ne vous donnant simplement pas les instructions nécessaires pour le corrompre. Des failles dans les implémentations JVM peuvent faire varier votre kilométrage.

+0

Je ne suis pas d'accord avec les commentaires de Java 6. La nouvelle fonctionnalité de l'analyse d'échappement permet potentiellement à la JVM d'éviter la création d'objets. Ainsi, les composants primitifs de ce qui aurait été l'objet (int, float, références, etc.) se retrouvent sur la pile. Les objets n'existent que dans le tas. Période. –

+1

Une autre page IBM, http://www.ibm.com/developerworks/library/j-jtp01274.html, n'est pas d'accord avec vous John M. Il semble que Java puisse effectivement allouer des objets sur la pile. –

+0

@StevenSchlansker lien vers le bas .. – Pacerier