程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 通過JVM查看關於Apache Geronimo的統計信息

通過JVM查看關於Apache Geronimo的統計信息

編輯:關於JAVA

簡介:Apache Geronimo 應用服務器不僅是開放源碼的,而且性能很高。所以 它是運行高性能應用程序的自然選擇。但是,只是將應用程序運行在 Geronimo 中還不能保證它滿足您的性能要求。有時候,可能需要分析和優化應用程序的效 率。有許多工具可用於該任務,但您可以通過分析 Java™ 虛擬機 (JVM) 統計信息基本完成該任務。本文將幫您體驗如何從 JVM 獲得統計信息,從而對應 用程序進行概要分析和優化,以滿足性能需要。

JVM 統計信息

JVM 提供許多統計信息。這些統計信息涉及諸如即時 (JIT) 編譯、類加載、 內存分配以及最有趣的垃圾收集之類基本的 JVM 特性。

即時編譯

JVM 可將字節代碼即時編譯為機器代碼。該動作類似於像您用於腳本語言的解 釋器(如 Perl)所執行的動作。但是它更先進,提供許多優化措施,使得已解釋 的字節代碼幾乎與預編譯的代碼運行得一樣快(有時更快)。顯然,執行 JIT 編 譯需要開銷。度量應用程序需要多大開銷的兩個有用的統計信息是 JIT 編譯次數 和執行這些編譯花費的時間總量。

類加載

JVM 負責從應用程序的類使用的庫向應用程序和類中加載類。因此,這些類可 能是從已部署在 Geronimo 中的 WAR 或 EAR 中加載的類,也可能是包含在 WAR 或 EAR 中的 JAR 文件,或者是由 Geronimo 容器加載的 JAR 中的類。如果類不 用於延長的時間,則 JVM 還可以選擇卸載這些類。這將導致幾項重要的統計信息 :加載的類的數量、卸載的類的數量、加載和卸載類花費的時間。

內存(堆)分配

在 Java 技術中沒有 malloc() 函數,這是因為 JVM 可自動為對象分配內存 。對象從堆中分配;因此,使用的和空閒的堆內存數量是兩個非常重要的統計信 息。監視堆分配是檢測可怕的內存洩漏最簡單的方法之一。

垃圾收集

這可能是 JVM 最有趣的統計信息。正像 JVM 為對象分配內存一樣,它還回收 不再使用的對象上的內存。關於垃圾收集如何工作,包括您可以指示 JVM 用於其 垃圾收集器的不同算法,有很多有趣的讀物。

還有許多關於垃圾收集器本身的有趣的統計信息。首先是調用垃圾收集器的頻 率和垃圾收集過程中花費的時間。垃圾收集的開銷很大,因為本質上它會中止應 用程序的執行以便可以檢驗對象。顯然,大量的垃圾收集可以真正減慢應用程序 的運行速度。

其他有趣的統計信息與對象分代有關。垃圾收集器按代對對象進行分類,每代 都指示對象已經經歷了一定次數的垃圾收集。(經歷很多次垃圾收集的對象比未 經歷或者經歷了很少次數垃圾收集的對象被垃圾收集的可能性更小。)這樣的對 象分類允許垃圾收集器檢驗更少的對象,使每次垃圾收集速度更快。因此,每代 中對象的數量可能相當有趣,提供更好的方法來查找內存洩漏和很好的方法來考 察潛在優化(如對象緩存和對象池)的影響。

訪問 JVM 統計信息

有幾個可用的 JVM 實現,但最常見的是 Sun 的 HotSpot JVM。從 Java 2 Platform, Standard Edition (J2SE) 1.4.2 開始,HotSpot 進行了全面配備, 提供許多上面描述的有用的統計信息。有好幾個方法用於獲得和分析這一數據。 獲得 JVM 生成的統計信息之後,您可以訪問 Geronimo 的 JVM 並分析您的應用 程序。

訪問方法

獲得一些 JVM 統計信息的最簡單的方法是通過命令行。HotSpot 識別許多命 令行選項,其中幾個選項允許您定制堆大小和垃圾收集選項。也可以使用 - verbose:gc 選項。這可使 JVM 打印出以下形式的行:

[GC 70333K->65666K(98896K), 0.0007817 secs]
[Full GC 65666K->59333K(98896K), 0.0205250 secs]


上面示例中的第一行指示發生了一次垃圾收集。收集之前堆上使用了 70,333KB,收集之後使用了 65,666KB。第一行還指示總共有 98,896KB 的可用空 間。最後,指出垃圾收集花費的時間,也即應用程序中止的時間量。第二行指示 相同的信息,但表示一個完整的垃圾收集。完整的垃圾收集涉及 JVM 對堆上所有 的對象進行檢驗,包括經歷了許多代、在部分垃圾收集上不會被分析的對象。

有關更詳細的信息,請使用 -XX:+PrintGCDetails 和 - XX:+PrintGCTimeStamps 選項。這些選項提供關於堆上對象的不同代的詳細信息 。

對於看上去更為有趣的統計信息,可以使用專門的工具。開放源碼的工具和商 業工具都可以使用。還可以使用 Sun 提供的一些用於與 HotSpot 一起使用的工 具。jvmstat 項目包含幾個用於監視 JVM 統計信息的工具,包括一個叫做 Visual Garbage Collector 或 visualgc 的圖形工具, 它使用起來相對簡單。 您需要 Java 5 或更高版本來運行 jvmstat,盡管它可以附加和監視 1.4.2 或更 高版本的 JVM。只需下載和解壓即可。將它添加到您的路徑,即可准備運行。啟 動了 Java 進程時,請使用 jps 工具來通過鍵入 jps 標識其 JVM。它向您提供 一個正在運行的 Java 進程的列表,這些進程以其 JVM 作為 ID。然後使用您想 監視的進程的 ID 調用 visualgc。jvmstat 發行版包括一個用於調用 visualgc 的 shell 腳本。如果安裝了 cygwin 這樣的工具,就可以在 *nix 或 Microsoft® Windows® 上調用 visualgc 了。此外,也可以按以下方式 調用它:

java -Xbootclasspath/p:%JAVA_HOME%\lib\tools.jar -jar % JVMSTAT_HOME%\jars\visualgc.jar 316

其中 JAVA_HOME 環境變量指定安裝 JDK 的位置,而 JVMSTAT_HOME 指示安裝 jvmstat 包的位置 。該行末尾的 316 是您想監視的 JVM 的 ID。該 jvmstat 包還包括一個 jstat 工具。它提供在 visualgc 中看到的絕大部分相同信息,只不過將其作為文本輸 出。這對收集統計信息而言至關重要,然後可以將這些統計信息拖入另一個程序 ,以對其進行深入分析、生成有關它的報告,等等。本文集中討論使用 visualgc 對這些統計信息進行可視化。

清單 1 提供一個短程序,您可以運行來測 試使用 jvmstat 進行監視。

清單 1. 測試用 jvmstat 進行監視

StatGen.java 
import java.util.ArrayList;
import java.util.List;

public class StatGen {

  static final int MAX_BLOCK = 8*1024*100;

   public static void main(String[] args) {
    try{
       int numLoops = 1;
      if (args.length >  0){
         numLoops = Integer.parseInt(args[0]);
      }
      System.out.println ("#loops="+numLoops);

      List<long[]> list  = new ArrayList<long[]>(numLoops);
      for (int  i=0;i<numLoops;i++){
        int sz = (int)  (Math.random()*MAX_BLOCK);
        long[] garbage = new  long[sz];
        if (sz % 5 == 0){
           list.add(garbage);
        }
         System.out.println("Sleeping 0.5s");
         Thread.sleep(500);
      }
       System.out.println("Done");
    } catch (Throwable t) {
       t.printStackTrace();
    }
     System.exit(0);
  }
}

這是一個簡單的程序。它使用了泛型,所以您需要 Java 5 。如果願意,您可 以容易地改變它以不使用泛型,然後它將用較舊的 JDK 運行。它通過創建可隨機 調整大小的長整數數組導致內存分配。它通過隨機將這些數組的一部分(大約 20%)放入一個列表來模擬內存洩漏。因此,垃圾收集器可以回收在每個循環上分 配的大多數內存,但它不能回收添加到列表中的數組。您可以試驗一些參數,比 如睡眠大小和最大塊大小。它還可以接收命令行參數,所以您可以容易地告知它 要執行多少次循環。

編譯 StatGen 之後,您可以簡單地從 java StatGen 100 開始。這執行 100 次循環。記住,您可以在命令行指定最小和最大堆大小。采用不同的最小和最大 堆大小在運行 visualgc 時將產生截然不同的視覺效果。您還可以指定不同的垃 圾收集算法;用 visualgc 監視 StatGen 時,將很好地理解這些算法的區別。

圖 1 展示了一些用 StatGen 運行 visualgc 的示例輸出。

圖 1. 用 StatGen 運行 visualgc

圖 2 展示了最有趣的窗口。它首先展示了 JIT 編譯。在本例中,只有三個窗 口,這對於這樣一個簡單的示例來說並不稀奇。它還展示了類加載器信息 —— 再說一遍,這很簡單,因為應用程序太簡單了。

圖 2.基本的 JVM 信息和堆使用情況

接著,它展示了總體的垃圾收集統計信息。您會看到 123 次收集和進行垃圾 收集所花費的總時間約為 0.3 秒。從第一個圖形中,您可以看到應用程序運行了 大約 100 秒,所以進行垃圾收集花費了該時間的 0.3%。

還有關於不同分代的統計信息。Eden 空間顯示了從未通過垃圾收集的新對象 。示例代碼生成許多這樣的新對象,並且它們很快就被收集掉。

注意兩個 Survivor 空間。它們基本上是較小的經歷過少數幾次垃圾收集的對 象集。所有對象要麼是立即准備收集的,要麼是從未准備收集的,所以,如果它 們到了 Survivor 空間,就將很快改變這種狀態。

接下來是較老的一代。這些對象經歷了大量垃圾收集。您可以看到穩定的對象 增加,表明存在潛在的內存洩漏。最後,您看到的是 JVM 確定永遠不會被收集的 對象的永久代。

直方圖窗口(參見 圖 3)展示了關於 Survivor 空間的數據 —— 此處列出 的不多。

圖 3. 展示關於 Survivor 空間的數據的直方圖窗口

Geronimo 和初始構建

在您前面下載的二進制和源安裝中有幾個目錄。二進制下載包括運行和使用 Geronimo 所必需的 Geronimo 的梗概。源下載包括所有 Geronimo 源代碼,包括 用於構建整棵樹的 Maven 構建腳本。首先來看二進制發行版,然後再看源代碼發 行版。

關於 Geronimo 示例應用程序的 JVM 統計信息

Geronimo 附帶了幾個示例 Web 應用程序。既然您有了一些從 JVM 提取 JVM 統計信息的工具,就可以容易地為 Geronimo 應用程序執行此操作。

啟動 Geronimo

僅僅啟動 Geronimo 並用 visualgc 監視它就相當有趣,如 圖 4、圖 5 和 圖 6 所示。

圖 4. 啟動 Geronimo 並用 visualgc 進行監視

圖 5. 展示 JIT 編譯、類加載器信息和垃圾收集的圖形

圖 6. Survivor Age Histogram

用標准的 java -jar %GERONIMO_HOME%/bin/server.jar 命令啟動 Geronimo 。僅通過使用啟動命令上的 -server 選項即可獲得直接視圖,如 圖 7 所示。

圖 7. 使用啟動命令上的 -server 選項

注意,JIT 編譯少得多。這是因為在您使用 -server 選項啟動 JVM 時加載了 更多的類。默認的啟動模式設計用於更快的啟動,以適應桌面應用程序。

在這兩種情況下,您都會在堆上看到許多長時間運行的對象,但是一旦 Geronimo 完全啟動,這個數量將趨於平緩。這展示所有正在被加載的服務器對象 ,如各種 GBeans 以及它們管理的服務。Geronimo 開發人員將因看不到內存洩漏 的跡象而高興,因為老的一代和永久的一代分配趨於平緩。

示例 Web 應用程序

現在您也可以運行一些包含的 Geronimo Web 應用程序。圖 8 中的圖形展示 JSPX-XHTML 示例應用程序的垃圾收集動作。

圖 8. JSPX-XHTML 示例應用程序的垃圾收集動作

您可以看到左側的對象突然增多,然後大部分對象將在呈現該頁面後消失,這 與您所期望的一樣。您可以看到也對應於應用程序運行的 JIT 編譯和類加載事件 。

既然了解了如何訪問和分析運行 Geronimo 的某個示例 Web 應用程序時生成 的 JVM 統計信息,就可以開始分析自己的應用程序了。大概就是啟動 Geronimo 、啟動 visualgc,然後部署和/或啟動您的應用程序。對它運行一些事件,觀察 它加載類、編譯字節代碼以及管理內存。

結束語

JVM 統計信息在調優應用程序時非常寶貴。Sun 提供的工具讓您快速分析應用 程序、執行優化並查看優化的效果。它們還允許試驗多個 JVM 選項,以對應用程 序執行附加調整。Geronimo 的目標之一是提供高性能應用服務器,而 JVM 統計 信息的分析是尋求最高應用程序性能的一項重要補充。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved