2

Eclipse has a convenient feature when you're paused in the debugger that shows an ID for every instance. They appear to be sequential and based on when an instance was allocated:

Example of IDs in a debugging session

I find these extremely useful when I'm digging into a substantial problem, as they're usually small integers that are a lot easier to remember than the full hash codes, or some other internal ID. They're a very quick check for "is this still the object I think it is?" when you're stepping through complex and deep callstacks.

Are these allocation IDs tracked by the jvm itself, or are they something Eclipse is providing through some unknown mechanism?

Is there any way to get at them from code, so that I can temporarily put them in log messages while debugging?

I don't really want to add an ID field to every object, there's many good reasons why that is a Bad Idea.

Stik
  • 519
  • 4
  • 17
  • 1
    You might want to check this question https://stackoverflow.com/questions/3289550/java-object-id-in-jvm – Pillz Jul 13 '20 at 20:36
  • I think this is the `uniqueID` field of the `com.sun.jdi.ObjectReference` interface which is part of the Jave Debug Interface (JDI) only available to code debugging a JVM. – greg-449 Jul 13 '20 at 20:40

1 Answers1

4

Are these allocation IDs tracked by the jvm itself, or are they something Eclipse is providing through some unknown mechanism?

Object IDs are generated by JDWP agent. JDWP agent is a library that exposes JVM debugging capabilities to external Java debuggers (like Eclipse IDE) through the JDWP protocol.

The agent is typically started with the JVM by the command line option -agentlib:jdwp= or -Xrunjdwp.

They appear to be sequential and based on when an instance was allocated

IDs are generated on demand when the agent needs to send an object reference to the debugger. They are not related to object creation time or something. Java objects initially have no assigned IDs.

Is there any way to get at them from code

As I said above, object IDs do not exist until the agent exchanges object references with the debugger.

But you may generate your own IDs for objects using IdentityHashMap or similar. Here is a simplest way to create such IDs:

private static final Map<Object, Long> map = new IdentityHashMap<>();

private static long nextId;

public static long getId(Object o) {
    synchronized (map) {
        Long id = map.get(o);
        if (id == null) {
            map.put(o, id = ++nextId);
        }
        return id;
    }
}

Of course, this implementation is not perfect, since it uses a global lock and stores objects forever. A better solution would be a kind of WeakIdentityConcurrentMap.

In fact, this is exactly how JDWP agent generates object IDs. It keeps an internal hash table that maps an object to a sequentially inceremented integer, and uses reference counting for removal. See commonRef.c

apangin
  • 92,924
  • 10
  • 193
  • 247