2010-05-14 51 views
2

我只是在Eclipse的調試器中設置了一個條件斷點,並通過斷點標準來檢查一個HashMap的值列表(8個元素)是否包含Double.NaN。這導致了性能的顯着下降 - 大約五分鐘後,我放棄了。關於Eclipse Java調試器的問題條件斷點效率低下

然後我複製粘貼條件成一條if語句在完全相同的行,在if中放置一個noop,並在那裏設置一個正常的斷點。這個斷點在預期的20-30秒內達到了。

有沒有什麼特別的條件斷點可以使性能命中值得,或者是Eclipse的實現有點愚蠢?看起來他們很容易在幕後做同樣的事情(粘貼if和compile)。

回答

2

有趣!

我玩了一些源代碼,看看有沒有條件斷點發生了什麼。附在下面。

執行與條件斷點調試器:
時間: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); 
} 


} 
0

斷點通過了多少次?可能調試器在觸發之前必須多次測試斷點條件。我不知道它是如何實現的,但是如果調試器執行的條件比通常編譯的Java效率低很多,我不會感到驚訝。也許只是它從JIT獲得的關注較少。也許它甚至沒有完全編譯爲Java,並被解釋。

0

Eclipse需要停止整個JVM才能檢查斷點狀況。這就是爲什麼它會讓你付出代價。