38

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

sidharth sharma
  • 3,025
  • 6
  • 23
  • 20

4 Answers4

43

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
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
prunge
  • 22,460
  • 3
  • 73
  • 80
  • 5
    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. – BeeOnRope Dec 18 '12 at 05:58
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).

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • 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++? – Martijn Courteaux Aug 15 '11 at 00:04
  • 2
    `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. – templatetypedef Aug 15 '11 at 00:58
  • 1
    `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.) – Stephen C Aug 15 '11 at 01:03
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));
egorlitvinenko
  • 2,736
  • 2
  • 16
  • 36
  • 1
    a) Link-only answers aren't considered good answers here, please see [answer]. b) This question already has several other high-quality answers; what does this add? – EJoshuaS - Stand with Ukraine Aug 10 '17 at 02:16
  • 1
    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. – egorlitvinenko Aug 10 '17 at 07:20
-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'.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 8
    My credit card balances change, unfortunately they still exist. – weston Feb 12 '17 at 21:59
  • 2
    @weston Your credit card balance changes, therefore you cannot rely on it always being the same. – user207421 Jun 13 '17 at 19:28
  • 2
    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 Jun 13 '17 at 19:56
  • @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. – user207421 Jun 09 '18 at 10:10
  • There is no mention of the address being unique at all in the question. And there is definitely a specific memory address assigned to every object that JVM creates, even if it changes in course of time , so your assertion is wrong. – Bhaskar Dec 30 '18 at 19:28
  • 1
    @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. – Holger Apr 08 '22 at 08:43