代码之家  ›  专栏  ›  技术社区  ›  Personman

Eclipse Java调试器条件断点无效问题

  •  2
  • Personman  · 技术社区  · 16 年前

    我刚刚在Eclipse的调试器中设置了一个条件断点,根据断点标准,它的条件有点低效——检查hashmap的值列表(8个元素)是否包含double.nan。这导致了一个非常明显的性能下降-大约五分钟后,我放弃了。

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

    是否有一些特殊的条件断点使性能受到影响,或者Eclipse的实现有点愚蠢?似乎他们可以很容易地在幕后做完全相同的事情(粘贴到if并编译)。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Carl Rosenberger    16 年前

    很有趣!

    我使用一些源代码来查看有条件断点和没有条件断点的情况。附在下面。

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

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

    imho由于第二个线程继续并排运行,所以虚拟机没有停止。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
  •  0
  •   Edmund    16 年前

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

        3
  •  0
  •   Valters Vingolds jpkroehling    16 年前

    Eclipse需要停止整个JVM以检查断点条件。这就是为什么你要付出代价。