【问题标题】:Question About Eclipse Java Debugger Conditional Breakpoints Inefficiency关于 Eclipse Java 调试器条件断点效率低下的问题
【发布时间】:2010-05-14 11:22:50
【问题描述】:

我只是在 Eclipse 的调试器中设置了一个条件断点,断点标准的条件有点低效 - 检查 HashMap 的值列表(8 个元素)是否包含 Double.NaN。这导致性能显着下降 - 大约五分钟后,我放弃了。

然后我将条件复制粘贴到完全相同的行的 if 语句中,在 if 中放置一个 noop,并在那里设置一个正常的断点。该断点在预期的 20-30 秒内到达。

条件断点有什么特别之处可以使性能受到影响,还是 Eclipse 的实现有点愚蠢?似乎他们可以很容易地在幕后做完全相同的事情(粘贴在 if 中并编译)。

【问题讨论】:

    标签: java eclipse performance debugging


    【解决方案1】:

    有趣!

    我使用了一些源代码来查看使用和不使用条件断点会发生什么。附在下面。

    在带有条件断点的调试器中执行:
    持续时间:1210623 微秒

    在没有条件断点的调试器中执行:
    持续时间:24 微秒

    恕我直言,VM 没有停止,因为第二个线程继续并行运行。 Eclipse 确实必须将断点代码注入当前类。也许它在每次调用时都会这样做,也许它必须在每次调用时重新编译类。检查 Eclipse 源代码将揭示到底发生了什么。

    我在 C# 和 Visual Studio 中运行条件断点的经验更糟:我的胃感觉是那里的情况要差几个数量级。

    public class BreakPointPlay {
    
    static int breakpointHits;
    
    static volatile int modifiedBySecondThread;
    
    static volatile boolean stopped;
    
    public static void main(String[] args) throws InterruptedException {
    
        Thread secondThread = startSecondThread();
    
        final long LOOPS = 1000;
        long counter = 0;
        long start = System.nanoTime();
        for (long i = 0; i < LOOPS; i++) {
    
            // place breakpoint here and set the condition to the
            // #breakPointCondition() method.
            counter += i;
    
        }
        long stop = System.nanoTime();
        long nanos = stop - start;
        long micros = nanos / 1000;
    
        System.out.println("\nDuration: " + micros + " microseconds\n");
    
        printInfo();
        stopped = true;
    
        secondThread.join();
    }
    
    private static Thread startSecondThread() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while(! stopped){
                    modifiedBySecondThread++;
                }
            }
        });
        thread.start();
        return thread;
    }
    
    private static void printInfo() {
        printModifiedBySecondThread();
        printThread();
        printClassLoader();
        printStackTrace();
        printModifiedBySecondThread();
    }
    
    private static void printStackTrace() {
        Exception exception = new Exception();
        exception.fillInStackTrace();
        exception.printStackTrace(System.out);
    }
    
    private static void printModifiedBySecondThread() {
        print("modifiedBySecondThread " + modifiedBySecondThread);
    }
    
    public static boolean breakPointCondition(){
        breakpointHits++;
        if(breakpointHits == 100){
            printInfo();
        }
        return false;
    }
    
    private static void printClassLoader() {
        print("ClassLoader " + new BreakPointPlay().getClass().getClassLoader());
    }
    
    private static void printThread() {
        print("Thread " + Thread.currentThread());
    }
    
    private static void print(String msg){
        System.out.println(msg);
    }
    
    
    }
    

    【讨论】:

      【解决方案2】:

      断点经过了多少次?可能是调试器在触发之前必须多次测试断点条件。我不知道它是如何实现的,但如果调试器执行条件的效率比正常编译的 Java 低很多,我不会感到惊讶。也许只是它从 JIT 中得到的关注较少。也许它甚至根本没有完全编译成 Java,而是被解释了。

      【讨论】:

        【解决方案3】:

        Eclipse 需要停止整个 JVM 以检查断点条件。这就是它让您付出代价的原因。

        【讨论】:

          猜你喜欢
          • 2023-04-07
          • 1970-01-01
          • 2013-01-01
          • 2012-07-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-18
          • 1970-01-01
          相关资源
          最近更新 更多