38

I want to know the location that JVM allocates to objects being placed in the system memory.

3
  • 20
    Ok, I'll ask: why? Commented Aug 14, 2011 at 22:41
  • 2
    Possible duplicate of Memory address of variables in Java Commented Oct 26, 2015 at 7:55
  • 3
    @CiroSantilli烏坎事件2016六四事件法轮功 No. That one is asking whether something is a memory address. This one is asking how to get the memory address. Commented Oct 7, 2016 at 6:35

4 Answers 4

44

This is something you probably don't want to do.

If you really want to do this, something like this code might help:

package test;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

public class Addresser
{
    private static Unsafe unsafe;

    static
    {
        try
        {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe)field.get(null);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static long addressOf(Object o)
    throws Exception
    {
        Object[] array = new Object[] {o};

        long baseOffset = unsafe.arrayBaseOffset(Object[].class);
        int addressSize = unsafe.addressSize();
        long objectAddress;
        switch (addressSize)
        {
            case 4:
                objectAddress = unsafe.getInt(array, baseOffset);
                break;
            case 8:
                objectAddress = unsafe.getLong(array, baseOffset);
                break;
            default:
                throw new Error("unsupported address size: " + addressSize);
        }       

        return(objectAddress);
    }


    public static void main(String... args)
    throws Exception
    {   
        Object mine = "Hi there".toCharArray();
        long address = addressOf(mine);
        System.out.println("Addess: " + address);

        //Verify address works - should see the characters in the array in the output
        printBytes(address, 27);

    }

    public static void printBytes(long objectAddress, int num)
    {
        for (long i = 0; i < num; i++)
        {
            int cur = unsafe.getByte(objectAddress + i);
            System.out.print((char)cur);
        }
        System.out.println();
    }
}

But

  • not portable across JVMs or even different versions
  • objects can move because of GC at any time, and cannot synchronize across GCs so results might not make sense
  • not tested across all architectures, endianess, etc. might make this not work everywhere
Sign up to request clarification or add additional context in comments.

1 Comment

It seems that unsafe.addressSize() on 64-bit Sun JDKs returns 8 even when UseCompressedOpps is on. Using unsafe.arrayIndexScale(Object[].class), which returns 4 in that case, seems to be more likely to work with this technique (after all, you are storing the object in an Object array). With compressed oops, the address returned is not a true address - it may be shifted right by 3 bits, etc.
10

Without using JVM-specific features this cannot be done. Java deliberately hides the location associated with each object to give the implementation more flexibility (the JVM often moves objects around in memory when doing garbage collection) and to improve security (you can't use raw pointers to trash memory or access nonexistent objects).

3 Comments

And how about the default implementation of Object.hashCode()? It returns the memory address of the object, isn't it? Does it use the Unsafe class which @prunge told about? I know it is a native method, so maybe this is simply a pointer-to-int cast in C++?
Object.hashCode() does not return the memory address of the object. It's implementation-specific. I spent several months working on a JavaScript implementation of a JVM where you can't work with raw addresses and implemented Object.hashCode() by just having a counter I incremented for each object. On some implementations this may be how Object.hashCode() works, but because many JVMs move objects around in memory you cannot rely on this being true.
System.identityHashcode(Object) is significantly more complicated than returning the memory address of an object ... even if that is what it seems to do. For a start, it has to return the same value even if the GC has moved the object. This typically entails saving the value in the object. (Some JVM's do this in a clever way that minimizes the overhead ... but you do pay in the end.)
4

You can use http://openjdk.java.net/projects/code-tools/jol to parse object layouts and get locations in memory. For one object you can use:

System.out.println(
    GraphLayout.parseInstance(someObject).toPrintable());
System.out.println("Current address: " + VM.current().addressOf(someObject));

2 Comments

a) Link-only answers aren't considered good answers here, please see How to Answer. b) This question already has several other high-quality answers; what does this add?
Thanks for the feedback. It is added reference to standard modern tool - JOL, which are not here. Is more clean and portable way, which for author's task take one row of code, instead of Unsafe example. I also added code examples for the question.
-7

I want to know the location that JVM allocates to objects

You can't, because it doesn't exist. It changes over time due to garbage-collector action. There is no such thing as 'the location'.

6 Comments

My credit card balances change, unfortunately they still exist.
@weston Your credit card balance changes, therefore you cannot rely on it always being the same.
They didn't say they needed to rely on it not changing. My point (joke) was that doesn't mean it doesn't exist. But anyway there are ways to pin it: JNI critical sections for example where the location is exact and guaranteed to be unchanging.
@weston The question reads, and I quote, 'I want to know the location that JVM allocates to objects being placed in the system memory.' As there is no such unique location, my answer holds.
@Bhaskar unless Escape Analysis proves an object to be purely local and the JVM’s optimizer decides to scalarize it. Then, the object doesn’t have an address. It’s fields may end up in CPU registers, fold with other variables proven to have the same value, eliminated completely when unused, and only in some cases, some of the fields may end up on the stack. With the absence of consecutive storage for an object’s fields, there is no address that could identify the object. In short, no, not every object has an address.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.