首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >VisualVM线程转储与堆转储不匹配?

VisualVM线程转储与堆转储不匹配?
EN

Stack Overflow用户
提问于 2017-11-05 08:16:55
回答 1查看 788关注 0票数 2

我编写了一个死锁示例代码,然后使用VisualVM分析它,我发现对象导致死锁,它的地址在线程转储和堆转储之间是不同的。

exmaple代码是:

代码语言:javascript
运行
复制
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();
        }
    }
}

然后运行示例代码,Integer.valueOf(1)Integer.valueOf(2)将导致死锁。但是,这些地址在线程转储和堆转储之间是不同的。

线程转储:

堆转储:

但是jstack命令结果匹配堆转储:

那么,为什么VisualVM的线程转储与堆转储不匹配呢?为什么jstack结果与VisualVM的堆转储匹配?

或者,我出了什么问题?

谢谢~

PS:我再次执行程序,并将应用程序快照、堆转储、线程转储和jstack日志上载到Google Drive

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-06 00:51:34

转储中的对象ID是该对象在Java中的地址。

GC可以在堆中移动对象。地址已经更改,这意味着在运行j堆栈时和使用VisualVM进行线程转储之间存在GC。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47119542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档