Search code examples
javajvmvisualvmjstack

VisualVM thread dump not matched with heap dump?


I written a dead lock example code and then use VisualVM analyze it, I find that the object caused dead lock, its address is different between thread dump and heap dump.

The exmaple code is:

package com.example.chapter4;

/**
 * @author Cnfn
 * @date 2017/11/05
 */
public class ThreadDeadlock {
    static class SyncAddRunnable implements Runnable {
        int a, b;

        public SyncAddRunnable(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public void run() {
            synchronized (Integer.valueOf(a)) {
                synchronized (Integer.valueOf(b)) {
                    System.out.println(a + b);
                }
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; ++i) {
            new Thread(new SyncAddRunnable(1, 2)).start();
            new Thread(new SyncAddRunnable(2, 1)).start();
        }
    }
}

Then run the example code, Integer.valueOf(1) and Integer.valueOf(2) will cause dead lock. But those address are different between thread dump and heap dump.

The thread dump:

threaddump

The heap dump:

heapdump

But jstack command result matchs heap dump:

jstack

So, why VisualVM's thread dump not match heap dump? Why jstack result match VisualVM's heap dump?

Or, something wrong with me?

Thank you~~~

PS: I execute program again, and upload application snapshot, heap dump, thread dump and jstack log to Google Drive


Solution

  • Object ID in the dump is the address of this object in Java Heap.

    GC can move objects across the heap. The fact that the address has changed means there was a GC between the moment when you ran jstack and when you made a thread dump with VisualVM.