WebApp

ディレクトリ構成

形式説明
JAR一般的なクラス群やライブラリ、JDBCドライバ等をまとめたもの
WAR1つのWebアプリケーション(ディレクトリ構造)をまとめたもの
EAR複数のWebアプリケーションをまとめたもの

JAR

ROOT          パッケージ名に従ったディレクトリ階層で classファイルを格納
├─ com        com.seパッケージのclassを格納する
|  └─ se
|     *.class     
|
└─ META-INF
    ejb-jar.xml
     MANIFEST.MF

WAR

ROOT
├─ WEB-INF      コンテキストルート直下に必ず作成する必要がある(クライアントが直接アクセスすることは出来ない)
|   │  web.xml    サーブレットとURLの紐付けや、その他の各種設定を行うファイル
|   │ *.tld     カスタムタグを使用する際に必要となる設定ファイル
|   │
|   ├─ classes   クラスファイルを配置
|   │
|   ├─ lib      クラスファイルをアーカイブ化(JARやZIP)したファイルを配置
|   │
|   └─ tags     カスタムタグに関連するタグファイル(*.tag、*.tagx)を格納
|            JARファイル内では、/META-INF/tags/*.tag *.tagx として格納
|
└─ META-INF     管理情報を格納するディレクトリ。jarコマンドによって自動的に作成される
     MANIFEST.MF  jarコマンドのバージョンなどが記載されている

EAR

ROOT
| *.jar
| *.war
|
└─ META-INF
    application.xml 
     MANIFEST.MF


 

Java起動オプション

パフォーマンスに有利に働くように各値の初期値は、各値の最大値と同じ大きさにする
NewSize は、最大ヒープ サイズの4分の1〜半分を目安とする

ヒープに関するオプション説明
-Xms1024mヒープ全体の初期値(1024MB)
-Xmx1024mヒープ全体の最大値(1024MB)
-XX:NewSize=256mNew 領域の初期値(256MB)
-XX:MaxNewSize=256mNew 領域の最大値(256MB)
-XX:PermSize=256mPermanent 領域の初期値(256MB)
-XX:MaxPermSize=256mPermanent 領域の最大値(256MB)
GCに関するオプション説明
-verbose:gc基本的なGC情報を出力
-XX:+PrintGCDetailsGCの詳細情報を出力
-Xloggc:<ファイル名>ログの出力先
-XX:+PrintGCDateStampsタイムスタンプを出力
-XX:+UseGCLogFileRotationログローテーションの有効化
-XX:NumberOfGCLogFiles=<数>ログファイルのローテーション数
-XX:GCLogFileSize=<サイズ>ログファイルのローテーションサイズ (例) -XX:GCLogFileSize=10M
GCアルゴリズムオプション説明
-XX:+UseSerialGCYC/OC:アプリ停止し単一スレッドで行う
-XX:+UseParallelGCYC:アプリ停止し複数スレッドで行う
-XX:+UseParallelOldGCOC:アプリ停止し複数スレッドで行う(UseParallelGCと併用して使用、Java7u4ではデフォルトで有効)
-XX:+UseConcMarkSweepGCOC:バックグラウンドスレッドを使い最小限のアプリ停止で行う
-XX:+UseParNewGCYC:アプリ停止し複数スレッドで行う(UseConcMarkSweepGCと併用して使用)
-XX:+UseG1GCYC:アプリ停止し複数スレッドで行う。OC:バックグラウンドスレッドを使い最小限のアプリ停止で行う

パラメータ毎に改行して出力するには以下のコマンドを実行する。

ps -ef | egrep -i java | perl -p -e 's/-/\n-/g'


 

Javaリソース監視

jvisualvm.exe

Java SDKインストールディレクトリにあるjvisualvm.exeをクリックで起動。
ローカルツリーの下に「Tomcat」が表示されているので、それを選択することで各種状況が確認できる。
Windowsの場合、サービスから起動している時は表示されない(SYSTEMユーザで実行される為)。PSToolを使用しダンプ出力する必要あり。

jstat (参考

Java 仮想マシン統計データ監視ツール(JDKインストールディレクトリ内のbinフォルダに格納)
対象のPIDは jps -v コマンドにて確認する

jstat オプション PID [interval[s|ms] [count]] ]
オプション説明
classクラスローダーの動作に関する統計データ
compilerHotSpot Just-in-Time コンパイラの動作に関する統計データ
gcヒープのサイズとGC回数に関する統計データ
gccapacity世代ごとの容量と対応する領域に関する統計データ
gccauseガベージコレクション統計データの概要 (-gcutil と同じ) と、直前および現在 (適用可能な場合) のガベージコレクションイベントの原因
gcnewNew 世代の動作に関する統計データ
gcnewcapacityNew 世代のサイズと対応する領域に関する統計データ
gcoldOld 世代および Permanent 世代の動作に関する統計データ
gcoldcapacityOld 世代のサイズに関する統計データ
gcpermcapacityPermanent 世代のサイズに関する統計データ
gcutilガベージコレクション統計データの概要
printcompilationHotSpot コンパイル方法の統計データ
-tJVMの起動時からの経過時間を先頭列に追加
-h 値何行ごとにヘッダーを出力するか

(例)ガベージコレクションの統計データを1秒毎に5回取得

# ./jstat -gcutil -t 29874 1s 5
Timestamp         S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
      2934528.6   0.00   0.00   8.00  21.21  99.84    821    2.316   816   60.206   62.521
      2934529.6   0.00   0.00   8.00  21.21  99.84    821    2.316   816   60.206   62.521
      2934530.6   0.00   0.00   8.00  21.21  99.84    821    2.316   816   60.206   62.521
      2934531.6   0.00   0.00   8.00  21.21  99.84    821    2.316   816   60.206   62.521
      2934532.6   0.00   0.00   8.00  21.21  99.84    821    2.316   816   60.206   62.521
説明説明
S0Survivor 領域 0 の使用率 (現在の容量に対するパーセンテージ)YGC若い世代の GC イベント数
S1Survivor 領域 1 の使用率 (現在の容量に対するパーセンテージ)YGCT若い世代のガベージコレクション時間
EEden 領域の使用率 (現在の容量に対するパーセンテージ)FGCフル GC イベント数
OOld 領域の使用率 (現在の容量に対するパーセンテージ)FGCTフルガベージコレクション時間
PPermanent 領域の使用率 (現在の容量に対するパーセンテージ)GCTガベージコレクション総時間
# jstat -gc `ps -ef | grep jav[a] | awk '{print $2}'` 5s
S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   
512.0  512.0   0.0   498.2   4416.0   3371.4   10944.0     5683.7   524288.0 4999.2      7    0.032   0      0.000    0.032
512.0  512.0   0.0   498.2   4416.0   3371.4   10944.0     5683.7   524288.0 4999.2      7    0.032   0      0.000    0.032
説明説明
S0CSurvivor 領域 0 の現在の容量 (KB)S1CSurvivor 領域 1 の現在の容量 (KB)
S0USurvivor 領域 0 の使用率 (KB)S1USurvivor 領域 1 の使用率 (KB)
ECEden 領域の現在の容量 (KB)EUEden 領域の使用率 (KB)
OCOld 領域の現在の容量 (KB)OUOld 領域の使用率 (KB)
PCPermanent 領域の現在の容量 (KB)PUPermanent 領域の使用率 (KB)
YGCYoung 世代の GC イベント数YGCTYoung 世代のガベージコレクション時間
FGCフル GC イベント数FGCTフルガベージコレクション時間
GCTガベージコレクションの合計時間

xC(現在の使用量)は 仮想メモリとして確保され、xU(使用率)が実際に物理メモリとして確保されているっぽい。
FullGCなどでヒープの使用率が下がったとしても、物理メモリの使用率は減らない模様。

ヒープ領域

JavaHeap.png

領域説明
NewSurvivor(From、To)、Eden領域の2つに分類される。Survivorは更にFromとToの領域がある
プログラム実行中にオブジェクトが新たに作成されるとEden領域に配置される
Eden領域が一杯になるとScavenge GC が実施され破棄されるが使用中のオブジェクトはTo領域に移動する
再度Scavenge GCが実行した際、前回To領域に移動したオブジェクトが使用中だと今度はFrom領域に移動する
使用中オブジェクトはToとFromを交互に行き来する
デフォルトでは32回使用中が続いた場合、使用頻度が高いオブジェクトとしてOld領域に移動する
OldOld領域が一杯になるとFull GCが実行される
Permanentクラスやメソッドの情報を格納。Permanet領域が一杯になるとFull GCが実行される


JRockitHeap.png

Javaの Survivor に相当する領域はなく Nursery が Full になると即座に Oldに移行する
Oldも一杯になるとFullGCが実行される

 

Java Flight Recorder(jcmd)

java の起動オプションに以下を指定し有効化する。

-XX:+UnlockCommercialFeatures -XX:+FlightRecorder

フライトレコーダーの記録。(Java 7 update 40 以降の JDK で使用可能)

jcmd <PID> [help] [コマンド]
コマンド説明コマンド説明
JFR.startJFRの記録開始VM.versionJVMのバージョン取得
JFR.stopJFRの記録停止VM.uptimeJVM実行時間を取得
JFR.checkJFRの実行状態確認VM.command_lineコマンド引数確認
JFR.dumpJFRのDUMP出力VM.flags [-all]有効化されてるチューニングフラグの確認。-all 取得した際、:= はデフォルト以外の値が設定されている
一番右に表示される product はプラットフォーム毎に共通のデフォルト値で、pd productは共通でないことを意味する

Java Platform, Standard Edition Java Flight Recorder ランタイムガイド

 

スレッドダンプ(jstack)

-- PID確認
$JAVA_HOME/bin/jps

-- スレッドダンプ取得
$JAVA_HOME/bin/jstack <PID>

-- コンソールログに結果を出力させる場合
kill -3 <PID>


 

ヒープダンプ(jmap)

-- ヒストグラムの表示
jmap -histo <PID>    ‥‥次回のFullGCで削除されるオブジェクトを含む
jmap -histo:live <PID> ‥‥FullGCを行ってから表示する(使用中のオブジェクトのみ表示される)
-- DUMPファイルを出力
jmap -dump:live,format=b,file=<出力ファイル名> <PID>

Windowsの場合はPSToolを使用する。
PsExec.exeを利用することで、SYSTEMユーザでコマンドの実行が可能。

> PsExec.exe -s "jps"  ※TomcatのPIDが表示されることを確認
> PsExec.exe -s "jmap" -dump:format=b,file=<ファイルパス> <PID>


 

スタックトレース解析

HiLevelException: HiLevel         ‥‥例外クラス名と、エラーメッセージ
    at Test.parentMethod(Test.java:19)  ‥‥エラー発生箇所
    at Test.<init>(Test.java:9)      ‥‥上記関数の呼び出す元
    at Test.main(Test.java:4)       ‥‥上記関数の呼びだし元
Caused by: LowLevelException: LowLevel  ‥‥スタックトレースの原因は、LowLevelExceptionである
    at Test.childMethod(Test.java:24)
    at Test.parentMethod(Test.java:17)
    ... 2 more              ‥‥Caused by の直前の2行が続きのスタックとなる
                       つまり、以下の通り続く。
                       at Test.<init>(Test.java:9)
                       at Test.main(Test.java:4)

ソースサンプル

  • JDBCによるDBアクセス
    クラスパスに JDBCの jar を指定する(OracleClientの場合、$ORACLE_HOME/jdbc/lib配下にある)
    export CLASSPATH=$CLASSPATH:$ORACLE_HOME/jdbc/lib/ojdbc5.jar:.
    ※ カレントディレクトリへのパスも通す為、最後に . も付与している
    import java.sql.*;
    import oracle.jdbc.*;
    import oracle.jdbc.pool.OracleDataSource;
    class JDBCVersion {
        public static void main (String args[]) throws SQLException
        {
            OracleDataSource ods = new OracleDataSource();
            // UID/PASS<IP>:<Port>/<SID>
            String url = "jdbc:oracle:thin:scott/scott@192.168.11.21:1521/orcl"
            ods.setURL(url);
            Connection conn = ods.getConnection();
    
            // Create Oracle DatabaseMetaData object
            DatabaseMetaData meta = conn.getMetaData();
    
            // gets driver info:
            System.out.println("JDBC driver version is " + meta.getDriverVersion());
        }
    }
  • 引数の受け渡しと待機
    public class Sleep {
        public static void main (String[] args) {
            if (args.length != 1) {
                System.err.println("引数が不正です");
                System.err.println("arg1:停止時間(秒)");
                System.exit(1);
            }
            try{
                System.out.println("SLEEP:" + args[0]);
                Thread.sleep(Integer.parseInt(args[0])*1000);
            } catch(InterruptedException e){}
        }
    }
  • コンパイルと実行
    # javac Sleep.java
    # java -cp . -XX:+PrintCompilation Sleep 10
        39    1             java.lang.String::indexOf (70 bytes)
        40    2             java.lang.String::hashCode (55 bytes)
    SLEEP:10
    ※ -XX:+PrintCompilation は メソッドやループがコンパイルされる度にメッセージを出力する。

     

Apache Struts

バージョン確認方法

struts.jar に含まれる META-INF/MANIFEST.MF ファイルの Specification-Version および Implementation-Version を確認する。

トップ   編集 凍結解除 差分 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-02-22 (水) 21:59:20 (243d)