Adresse mémoire des variables en Java


139

Veuillez jeter un œil à l'image ci-dessous. Lorsque nous créons un objet en java avec le newmot - clé, nous obtenons une adresse mémoire du système d'exploitation.

Lorsque nous écrivons, out.println(objName)nous pouvons voir une chaîne "spéciale" en sortie. Mes questions sont:

  1. Quelle est cette sortie?
  2. Si c'est l'adresse mémoire qui nous a été donnée par le système d'exploitation:

    a) Comment puis-je convertir cette chaîne en binaire?

    b) Comment puis-je obtenir une adresse de variable entière?

texte alternatif


5
eh bien, je ne vote pas parce que la question est assez claire, juste une suggestion que vous auriez dû la faire dans le texte pour que les gens puissent la rechercher
phunehehe

2
En utilisant sun.misc.Unsafe, il est possible d'obtenir l'adresse d'un objet java. Pour la liste des programmes, consultez: javapapers.com/core-java/address-of-a-java-object
Joseph Kulandai

la valeur pointée est une représentation hexadécimale du hashcode de l'objet a1 & a2
Naveen

Réponses:


167

C'est le nom de la classe et System.identityHashCode () séparés par le caractère «@». Ce que le code de hachage d'identité représente est spécifique à l'implémentation. Il s'agit souvent de l'adresse mémoire initiale de l'objet, mais l'objet peut être déplacé en mémoire par la machine virtuelle au fil du temps. Donc (brièvement) vous ne pouvez pas compter sur quoi que ce soit.

Obtenir les adresses mémoire des variables n'a pas de sens dans Java, car la JVM est libre d'implémenter des objets et de les déplacer comme bon lui semble (vos objets peuvent / vont se déplacer pendant le garbage collection, etc.)

Integer.toBinaryString () vous donnera un entier sous forme binaire.


33
Un autre point intéressant est que les codes de hachage d'identité ne sont pas garantis d'être uniques. Par exemple, sur la JVM 64 bits, il existe 2 ^ 32 codes de hachage d' identité mais 2 ^ 64 adresses mémoire .
Alex Jasmin

11
En fait, le code de hachage d'identité ne peut pas changer , sinon le contrat de hashCode () serait violé.
Matt McHenry

1
J'utilise ceci pour la journalisation / le débogage pour déterminer dans les journaux quand les objets pointent vers le même objet au lieu de ceux équivalents. À ces fins identityHashcode, cela n'a pas de sens, ce n'est tout simplement pas infaillible. :)
Sled

@BrianAgnew: Je veux savoir -> Pourquoi deux objets ont le même hashcode. Je suis confus car j'ai appris en c ou c ++ que chaque variable ou objet a un emplacement mémoire différent. Puis en java Comment peut identifier ou différencier deux objets avec le même hashCode.
Ved Prakash

1
@VedPrakash le hashcode d'objet permet aux objets d'être stockés dans des collections hachées. Si vous souhaitez différencier deux objets différents, vous pouvez simplement utiliser l'égalité de référence
Brian Agnew

36

Il est possible d'utiliser sun.misc.Unsafe: voir cette excellente réponse de @Peter Lawrey -> Existe-t-il un moyen d'obtenir une adresse de référence?

En utilisant son code pour printAddresses ():

    public static void printAddresses(String label, Object... objects) {
    System.out.print(label + ": 0x");
    long last = 0;
    int offset = unsafe.arrayBaseOffset(objects.getClass());
    int scale = unsafe.arrayIndexScale(objects.getClass());
    switch (scale) {
    case 4:
        long factor = is64bit ? 8 : 1;
        final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor;
        System.out.print(Long.toHexString(i1));
        last = i1;
        for (int i = 1; i < objects.length; i++) {
            final long i2 = (unsafe.getInt(objects, offset + i * 4) & 0xFFFFFFFFL) * factor;
            if (i2 > last)
                System.out.print(", +" + Long.toHexString(i2 - last));
            else
                System.out.print(", -" + Long.toHexString( last - i2));
            last = i2;
        }
        break;
    case 8:
        throw new AssertionError("Not supported");
    }
    System.out.println();
}

J'ai mis en place ce test:

    //hashcode
    System.out.println("Hashcode :       "+myObject.hashCode());
    System.out.println("Hashcode :       "+System.identityHashCode(myObject));
    System.out.println("Hashcode (HEX) : "+Integer.toHexString(myObject.hashCode()));

    //toString
    System.out.println("toString :       "+String.valueOf(myObject));

    printAddresses("Address", myObject);

Voici la sortie:

Hashcode :       125665513
Hashcode :       125665513
Hashcode (HEX) : 77d80e9
toString :       java.lang.Object@77d80e9
Address: 0x7aae62270

Conclusion :

  • hashcode! = adresse
  • toString = class @ HEX (hashcode)

13

C'est la sortie de l'implémentation "toString ()" d'Object. Si votre classe remplace toString (), elle affichera quelque chose de complètement différent.


6

Ce n'est pas une adresse mémoire C'est classname @ hashcode

classname = nom qualifié complet ou nom absolu (c'est-à-dire le nom du package suivi du nom de la classe)

hashcode = format hexadécimal (System.identityHashCode (obj) ou obj.hashCode () vous donnera le hashcode au format décimal)


4

Comme l'a dit Sunil, ce n'est pas une adresse mémoire, c'est juste le hashcode

Pour obtenir le même contenu @, vous pouvez:

Si hashCode n'est pas remplacé dans cette classe:

"@" + Integer.toHexString(obj.hashCode())

Si hashCode est remplacé, vous obtenez la valeur d'origine avec:

"@" + Integer.toHexString(System.identityHashCode(obj)) 

Ceci est souvent confondu avec l'adresse mémoire car si vous ne remplacez pas hashCode (), l'adresse mémoire est utilisée pour calculer le hachage.


1

Ce que vous obtenez est le résultat de la méthode toString () de la classe Object ou, plus précisément, de identityHashCode () comme l'a souligné uzay95.

"Lorsque nous créons un objet en java avec un nouveau mot-clé, nous obtenons une adresse mémoire du système d'exploitation."

Il est important de réaliser que tout ce que vous faites en Java est géré par la machine virtuelle Java. C'est la JVM qui donne ces informations. Ce qui se passe réellement dans la RAM du système d'exploitation hôte dépend entièrement de l'implémentation du JRE.



0

En Java, lorsque vous créez un objet à partir d'une classe comme Person p = new Person();, il ps'agit en fait d'une adresse d'un emplacement mémoire qui pointe vers un type de Person.

Lorsque vous utilisez un ensemble d'états pour imprimer, pvous verrez une adresse. Le newmot clé crée un nouvel emplacement mémoire contenant toutes les variables d'instance et les méthodes qui sont incluses dans class Personet pest la variable de référence pointant vers cet emplacement mémoire.


dans votre image, a1 et a2 sont deux adresses de mémoire différentes. C'est la raison derrière l'obtention de deux valeurs différentes.
Panduka Wedisinghe le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.