web-dev-qa-db-ja.com

遅いトレースJava Solaris10のI / O

Javaアプリケーションがありますが、Solaris10サーバーの方がWindowsPCよりも大幅に低速です。

アプリケーションのプロファイル(-Xprof)を行い、UnixFileSystem.getBooleanAttributes0メソッドがネイティブ呼び出しで約40%のCPU時間を消費することを確認しました。

検索を追跡して、動作が遅い原因を特定するにはどうすればよいですか?

更新:

dtraceを実行し、CPU時間は0.489秒であるのに対し、timeの結果は


real 0m40.759s
user 0m47.669s
sys 0m2.287s

時間はCPUではなく別の場所で費やされているようです。このdtraceの結果を得て、さらに調査を進めるにはどうすればよいですか?別のdtraceオプションを使用して、より多くの情報を表示できますか?

どうもありがとうございました。


# /dtrace-toolkit/DTraceToolkit-0.99/procsystime -aTp 5695
Tracing... Hit Ctrl-C to end...
dtrace: 1032 dynamic variable drops with non-empty dirty list
^C

Elapsed Times for PID 5695,

         SYSCALL          TIME (ns)
           gtime               7799
       sysconfig               8018
        lwp_kill              10105
     getsockname              10215
      systeminfo              10984
       getrlimit              11093
        lwp_self              20210
        schedctl              26361
    lwp_continue              27349
     priocntlsys              33390
          unlink              53050
     lwp_sigmask             136303
      setcontext             143447
   so_socketpair             202427
      lwp_create             223626
             brk             227141
       so_socket             263276
         memcntl             461091
           ioctl            1094955
lwp_cond_broadcast            1946728
lwp_mutex_wakeup            2579492
 lwp_cond_signal            2903277
            mmap            3082973
          access            4446250
        mprotect            4534229
      getdents64            5713309
          mmap64            6272480
            fsat            6925239
            stat            6926115
            open            8324983
           fcntl            8840868
           close           11264404
          llseek           11678791
          munmap           11867401
         fstat64           17852129
        lwp_park           22098570
          open64           23549922
          stat64           39673214
            read           41876097
     resolvepath           81905859
           yield          175946072
           write          225507878
lwp_mutex_timedlock          887174392
         pollsys        20393318412
   lwp_cond_wait       345099369278
          TOTAL:       367108549202

CPU Times for PID 5695,

         SYSCALL          TIME (ns)
           gtime               1208
       sysconfig               1647
        lwp_self               2198
      systeminfo               2856
        lwp_kill               3186
     getsockname               3625
       getrlimit               4613
    lwp_continue              13839
        schedctl              14059
     priocntlsys              14498
     lwp_sigmask              20541
          unlink              45801
      setcontext              96874
             brk             121804
        lwp_park             158601
   so_socketpair             195178
      lwp_create             209017
       so_socket             241199
         memcntl             365972
           ioctl             606397
lwp_cond_broadcast            1367556
lwp_mutex_wakeup            1561103
 lwp_cond_signal            1803831
          access            1885436
            mmap            2655710
          llseek            3266410
            open            3614795
            fsat            4043369
      getdents64            4253373
        mprotect            4345864
           close            4547395
           fcntl            4871095
            stat            5183012
          mmap64            5308789
         fstat64            8141116
          munmap           10774529
         pollsys           11928811
lwp_mutex_timedlock           19212980
          open64           19443958
   lwp_cond_wait           23144761
            read           28043647
          stat64           31710269
     resolvepath           70641662
           yield           77731698
           write          137678654
          TOTAL:          489282936

Syscall Counts for PID 5695,

         SYSCALL              COUNT
       getrlimit                  1
     getsockname                  1
           gtime                  1
        lwp_kill                  1
           rexit                  1
   so_socketpair                  1
       sysconfig                  1
      systeminfo                  1
          unlink                  1
    lwp_continue                  2
      lwp_create                  2
        schedctl                  2
        lwp_self                  3
     priocntlsys                  3
       so_socket                  3
        lwp_exit                  4
      setcontext                  7
        lwp_park                 11
         memcntl                 14
             brk                 16
     lwp_sigmask                 19
        mprotect                 25
            mmap                 56
          access                 67
lwp_cond_broadcast                 86
           ioctl                 87
            open                100
            fsat                129
          mmap64                133
lwp_mutex_wakeup                148
          munmap                153
 lwp_cond_signal                162
      getdents64                224
            stat                283
         pollsys                348
   lwp_cond_wait                537
lwp_mutex_timedlock                558
          open64                590
           fcntl                625
           close                777
          stat64               1146
          llseek               1368
            read               1404
         fstat64               1559
     resolvepath               1644
           yield              10049
           write              13416
          TOTAL:              35769

更新2:

これがdtraced Javaアプリケーションのソースです。1つの.jarファイルから数千のクラスをロードするだけで、より大きなアプリで観察されるのと同じ動作を再現します。

import Java.io.IOException;
import Java.io.InputStream;
import Java.util.Enumeration;
import Java.util.Properties;
public class TestCL {
    public static void main(String[] args) {
        Properties properties = new Properties();
        InputStream in = TestCL.class.getClassLoader().getResourceAsStream("TestCL.properties");
        if (in == null) {
            System.err.println("TestCL.properties not found");
            System.exit(-1);
        }
        try {
            properties.load(in);
        } catch (IOException e) {
            System.err.println("TestCL.properties loading error");
            e.printStackTrace();
            System.exit(-2);
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Enumeration e = properties.keys();
        while (e.hasMoreElements()) {
            String className = (String) e.nextElement();
            try {
                Class.forName(className);
                System.out.println("OK " + className);
            } catch (Throwable t) {
               System.err.println("KO " + className + " " + t.getClass().getName() + " " + t.getMessage());
            }
        }
    }
}

更新3:

すべてのクラスは、単一の.jarファイルにパックされています。また、すべてのクラスを解凍してテストを実行しましたが、パフォーマンスに大きな改善はありません。

Java -cp library.jar:. TestCL

5
fglez

Solarisを使用している場合は、dtraceを使用できるのは幸運です。これにより、カーネルレベルでプロファイルを作成し、jvmがカーネルとどのように相互作用しているかについてより多くの手がかりを得ることができます。

詳細はこちら

http://www.devx.com/Java/Article/3394

Jvmが何をしているのかを知りたい場合は、jvmプローブを使用してdtraceを実行します。

http://Java.Sun.com/javase/6/docs/technotes/guides/vm/dtrace.html

http://www.solarisinternals.com/wiki/index.php/DTrace_Topics_Java#DTrace_Topics:_Java

これにより、プログラムに関連してはるかに意味のある出力が得られます。 「メソッドタイム」セクションをご覧ください。

http://www.princeton.edu/~unix/Solaris/troubleshoot/diskio.html

i/Oボトルネックを見つけるための優れたガイドです。

これも役立つかもしれません http://prefetch.net/blog/index.php/2007/03/03/viewing-busy-code-paths-with-dtrace/

このような問題を追跡する際の厳格なルールはありませんが、情報が重要です!!。これらのガイドに従えば、忍者システムエンジニアになるための道を進んでいます。

Jprofilerを使用できる場合があります http://www.ej-technologies.com/products/jprofiler/overview.html

オープンソースではありませんが、Javaパフォーマンスの問題を追跡することに大成功しました。

また、Java vmとアプリケーションを完全なデバッグログで実行する必要があります。カーネルログにア​​クセスできる場合は、異常なイベントがないか確認してください。

幸運を。

サーバー障害のある他の誰かが、このような問題を見つけるための忍者のヒントを持っていますか?私は独自のデバッグ方法を持っていますが、他の人がどう思うかを知ることは興味深いでしょうか?

- - - - - - - - -更新 - - - - - - -

トレースをもう一度見てみましたが、多くのresolvepathを実行しているようです。

これは修正する必要があります。非常に長いパスを使用していますか、それともシンボリックリンクされたディレクトリから実行していますか。シンボリックリンクを削除するか、ハードリンクを使用して、より良い結果が得られるかどうかを確認してください。

アプリは多くのディレクトリトラバーサルを実行し、相対パスではなく絶対パスを使用してみますか?.

繰り返しになりますが、私はチーズケーキを食べ過ぎていました。 Javaプローブを使用してdtraceを実行します。これにより、ドリルダウンして、Javaクラス/メソッドが最も時間を費やしているものを確認できます。

幸運(再び)。今はあきらめないでください、私たちは解決に非常に近いと思います。

4

Solarisシステムでsys_diag -G -I1 -l -vを実行するだけで、すべてのパフォーマンス情報(CPU /メモリ/ネットワーク/ディスクIO/Dtrace /カーネル...)が集約され、結果の単一の色分けされた.htmlレポートで出力が分析されます。サブシステムごとにワークロードを特徴付ける/ bottlenecks ..これにより、発生している可能性のあるロック(lockstat、..)だけでなく、すべてのボトルネックが表示されます。最新バージョンはv8.1HTHです。

2
Todd Jobson

最終結果を投稿するだけです。

サーバー(Sun Tシリーズ)は、シングルスレッドのJavaアプリケーションの場合は非常に低速です。図を参照してください。

回答とサポートをありがとうございました。

1
fglez

dtrace出力は、アプリケーションがほとんどの時間を書き込みに費やしていることを示しています。チェックする必要があります(dtraceもちろん:-)を使用)whereこれらの書き込みは実行されます。彼らがsolarisファイルシステムに行く場合は、ファイルシステムがボトルネックではないかどうかを確認する必要があります。

1
pb100

Iostatを調べて、ディスクアクセスが予想よりも遅くなる原因となっている問題があるかどうかを確認することをお勧めします。数千のクラスをロードしても、特にブロックがキャッシュにあるように数回実行した場合は、多くのディスクIOを消費することはありません。

試してみてください

iostat -nxtcmpz 3

テストの実行中に、ビジー/待機の割合が特に高いデバイスがあるかどうか、または平均サービス時間が特に長いかどうかを確認します。死にかけているディスク、または応答しないNFSマウントの強制終了パフォーマンスがある可能性があります。

0
Chris