【问题标题】:Java Thread Profiling : Determine Thread waits for specific locks and duration of each waitJava Thread Profiling:确定线程等待特定锁和每次等待的持续时间
【发布时间】:2010-03-02 10:25:24
【问题描述】:

我有一个使用线程的 Java 应用程序,它使用多个 Lock 对象实例来同步对公共资源的访问。

现在作为性能测量的一部分,我想测量每个线程在每个锁中花费的时间。到目前为止,我已经尝试过 NetBeans 分析器。

Netbeans 分析器向我显示线程的总等待时间,但无法知道线程等待锁定的时间。

对于这种测量,您会推荐哪种工具?

干杯

【问题讨论】:

    标签: java profiling


    【解决方案1】:

    根据您需要的具体数据,您可以从 Java 程序中获取这些信息。例如,类似这样的操作将在 100 秒内每秒对持有的锁进行 20 次采样,从而有效地创建锁 > 锁定近似时间(锁定给定锁的“滴答”数)的映射:

    private static void runProfile() {
        try {
            final int noSeconds = 100;
            final int sleepMillis = 50;
            final int noSamples = noSeconds * 1000 / sleepMillis;
    
            ThreadMXBean thb = ManagementFactory.getThreadMXBean();
            Map<String,Integer> blockCounts = new HashMap<String, Integer>(50);
            for (int i = 0; i < noSamples ; i++) {
                long[] ids = thb.getAllThreadIds();
                ThreadInfo[] infs = thb.getThreadInfo(ids, 0);
                for (ThreadInfo ti : infs) {
                    LockInfo lockInf = ti.getLockInfo();
                    if (lockInf != null) {
                        String key = lockInf.toString();
                        Integer cnt = blockCounts.get(key);
                        blockCounts.put(key, cnt == null ? 1 : cnt+1);
                    }
                }
    
                Thread.sleep(sleepMillis);
            }
    
            System.out.println("Locks:");
            for (String lockName : blockCounts.keySet()) {
                System.out.println(lockName + " : " + blockCounts.get(lockName));
            }
        } catch (InterruptedException iex) {
            Thread.currentThread().interrupt();
        }
    }
    

    根据需要调整以收集数据。

    然后您可以在后台线程中启动它,例如:

        Thread thr = new Thread() {
            public void run() {
                runProfile();
            }
        };
        thr.setPriority(Thread.MAX_PRIORITY-1);
        thr.start();
    

    【讨论】:

    • @Neil 感谢您的回答,我想这是唯一的方法。不过,我想在运行过程之外执行此操作。是否可以?坦率地说,我没有使用新的管理 API 的经验。对于如何从另一个 JVM 执行此操作,多一点轻推/链接会很好。干杯
    猜你喜欢
    • 2012-07-05
    • 2014-01-24
    • 2017-08-26
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多