2011-11-15 54 views

回答

1

是沒有錯的例子。它看起來像updateInfoInDirection()調用new SequenceInfo()SequenceInfo.next()。 '自我時間'意味着時間花費在方法本身的代碼中(方法updateInfoInDirection()在採樣線程時位於堆棧底部)。

43

不幸的是採樣廓當它歸結爲深入分析是相當有限的,由於多種原因:

  • 採樣由採樣週期的限制:例如,VisualVM的目前有一個最小採樣週期爲20ms。現代處理器可以在那個時候執行數百萬條指令 - 當然綽綽有餘可以調用幾個簡短的方法並從中返回。

    雖然一個明顯的解決辦法是減少採樣週期,這也將增加分析器對您的應用程序的影響,呈現uncertainty principle的一個很好的例子。

  • 取樣容易被內聯代碼混淆: JVM和任何像樣的編譯器將內聯瑣碎和/或頻繁調用的方法,從而將他們的代碼在其調用者的代碼。採樣分析器無法判斷每種方法的哪些部分實際屬於它,哪些屬於內聯調用。

    在VisualVM的自時間的情況下實際上包括兩個方法任何內嵌代碼的執行時間。

  • 採樣器可能會被高級VM困惑:例如,在現代JVM實現中,方法沒有穩定的表示。想象一下,例如下面的方法:

    void A() { 
        ... 
        B(); 
        ... 
    } 
    

    當JVM啓動B()從字節碼解釋直線,從而採取了相當多的時間,這使得它的採樣可見。然後,一段時間後,JVM決定B()是一個很好的優化候選,並將其編譯爲本地代碼,從而使其更快。又過了一段時間,JVM可能決定將呼叫內聯到B(),並將其代碼合併到A()中。

    在最好的情況,採樣分析器將顯示這些第一次運行的成本和隨後的所有運行的成本將包含在主叫方所花費的時間。不幸的是,這可能會讓一個沒有經驗的開發人員誤以爲低估了內聯方法的成本。

    在最壞的情況,即成本可以被分配給一個兄弟姐妹通話,而不是調用者。例如,我目前使用剖析VisualVM的,其中一個熱點似乎ArrayList.size()方法的應用程序。在我的Java實現中,該方法是一個簡單的字段getter,任何JVM都應該快速內聯。然而,剖析器顯示它作爲一個主要的時間消費者,完全忽略了一堆附近的HashMap電話,這顯然要貴得多。

避免這些弱點的唯一方法是使用儀器分析器,而不是採樣分析器。檢測分析器,例如VisualVM中的Profiler選項卡提供的分析器實質上記錄了每個方法的入口並退出到選定的代碼中。不幸的是,插裝廓線儀對異形代碼相當沉重的影響:

  • 他們周圍插入每一個方法,它完全改變的方法是由JVM處理方式的監管碼。即使是簡單的字段getter/setter方法也可能因爲額外的代碼而不再內聯,從而導致任何結果偏差。分析人員通常試圖解釋這些變化,但並不總是成功的。

  • 他們造成巨大的起伏的輪廓代碼,這使得它們完全不適合用於監控完整的應用程序。

由於這些原因插裝分析器大多適合於分析已經被使用另一種方法,例如一個取樣分析器檢測的熱點。通過僅檢測選定的一組類和/或方法,可以將分析副作用限制到應用程序的特定部分。

相關問題