Memory address of variables in Java


Translate

Please take a look at the picture below. When we create an object in java with the new keyword, we are getting a memory address from the OS.

When we write out.println(objName) we can see a "special" string as output. My questions are:

  1. What is this output?
  2. If it is memory address which given by OS to us:

    a) How can I convert this string to binary?

    b) How can I get one integer variables address?

alt text



All Answers
  • Translate

    That is the class name and System.identityHashCode() separated by the '@' character. What the identity hash code represents is implementation-specific. It often is the initial memory address of the object, but the object can be moved in memory by the VM over time. So (briefly) you can't rely on it being anything.

    Getting the memory addresses of variables is meaningless within Java, since the JVM is at liberty to implement objects and move them as it seems fit (your objects may/will move around during garbage collection etc.)

    Integer.toBinaryString() will give you an integer in binary form.


  • Translate

    It is possible using sun.misc.Unsafe : see this great answer from @Peter Lawrey -> Is there a way to get a reference address?

    Using its code for 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();
    }
    

    I set up this 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);
    

    Here is the output :

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

    Conclusion :

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

  • Translate

    That is the output of Object's "toString()" implementation. If your class overrides toString(), it will print something entirely different.


  • Translate

    This is not memory address This is classname@hashcode

    where

    classname = full qualified name or absolute name (ie package name followed by class name)

    hashcode = hexadecimal format (System.identityHashCode(obj) or obj.hashCode() will give you hashcode in decimal format)


  • Translate

    Like Sunil said, this is not memory address.This is just the hashcode

    To get the same @ content, you can:

    If hashCode is not overridden in that class:

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

    If hashCode is overridden, you get the original value with:

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

    This is often confused with memory address because if you don't override hashCode(), the memory address is used to calculate the hash.


  • Translate

    What you are getting is the result of the toString() method of the Object class or, more precisely, the identityHashCode() as uzay95 has pointed out.

    "When we create an object in java with new keyword, we are getting a memory address from the OS."

    It is important to realize that everything you do in Java is handled by the Java Virtual Machine. It is the JVM that is giving this information. What actually happens in the RAM of the host operating system depends entirely on the implementation of the JRE.


  • Translate

    In Java when you are making an object from a class like Person p = new Person();, p is actually an address of a memory location which is pointing to a type of Person.

    When use a statemenet to print p you will see an address. The new key word makes a new memory location containing all the instance variables and methods which are included in class Person and p is the reference variable pointing to that memory location.


  • Translate