0

数分後にハングする Web アプリケーションがあります。基本的に、これは非常にカスタマイズされたフォームを作成およびプレビューするためのアプリケーションであり、数分間の集中的なユーザー操作の後、アプリケーションは動作を停止します。これは、要求が完了し、応答が返されないことを意味します。

Tomcat のログやアプリケーションのログにもハングに関する手がかりが見つからないため、「少し」迷っています。lambda/psi-probe を使用しているため、アプリケーション サーバーは実行されており、他のアプリケーションや面倒なアプリケーションも問題なくチェックできます (プローブ自体は別の Web アプリケーションです)。

アプリケーションは、長い間正常に動作していた休止状態を使用していますが、最近、パフォーマンスを向上させるために (休止状態のみを使用する場合、休止状態は多くのクエリを挿入します)、java.sql 標準 API を介してネイティブ SQL を導入しました。私は両方を混在させないように注意しており、それらは jsp でのみ使用されます。最初に休止状態でいくつかの (少数の) オブジェクトを取得し、次に jdbc でいくつかのロジックを使用します。jdbc を使用する前に、Hibernate セッションが閉じられます。

データベース接続の問題 (何度か確認しましたが、データベース サーバーは正常に動作しています)、デッドロックまたはランナウェイ スレッドについて読んだことがあります。VisualVM で VisualVM を使用して確認しました。

では、誰でもハングを見つけたりトラップしたりする手がかりを与えることができますか? 仮想のランナウェイ スレッドまたはデッドロックをキャッチまたはトラップするために VisualVM を使用する手がかりを得ることができますか? 待機中のスレッドと実行中のスレッドが表示されるだけなので、後者は私を啓発します。

私は tomcat 6.0.21 を使用しています (私は常に同じ結果で 7.0.11 を試しました) Mac osx および Linux (開発および試作マシン) で Java 1.6

どんなアイデアでも大歓迎です。

ウィリー

4

3 に答える 3

1

jconsoleを実行してみて(ハングしているマシンでこれを実行できない場合は、リモートJMXを有効にし、JVMを再起動してハングを再現する必要があります)、[スレッド]タブをクリックして[デッドロックの検出]をクリックします。 。それはいくつかの助けを提供するかもしれません。

あなたが言うように、使用する他のものはVisualVM、またはJCarderです。

編集

あなたのコメントを見た後、試すべきもう一つのことは次のとおりです:

  1. JConsoleを起動し、ハングしたVMに接続します
  2. MBeans→com.sun.management→HotSpotDiagnostic→Operationsに移動します
  3. dumpHeapその横に2つのテキストボックスで呼び出されるボタンがあります。最初のテキストボックスに、一意の名前を入力します-イニシャルや日付などを使用します- rt20110317。2番目のテキストボックスをtrueに設定したままにします。ボタンを押してdumpHeapください。

これにより、ヒープが大きなファイルに書き込まれます。このファイルを見つけて、EclipseMATにロードします。このツールは、VMの状態を確認するためのあらゆる種類の便利な要素を提供します。メモリリークを見つけるためのウィザードもいくつかあります。これは、同じ種類の症状が原因でVMがハングしている理由を見つけることもできます。

于 2011-03-16T15:48:00.947 に答える
1

私はこれに似た状況にありました。問題は、一部のデータベース接続が接続プールに戻されなかったことです。制限に達すると、アプリケーションはフリーズするだけで、例外やエラーは発生しません。あなたの場合もそうかもしれません。接続プールで放棄された接続のログを有効にします。不正な接続がないかどうかを確認することをお勧めします。

于 2011-03-16T16:36:08.720 に答える
0

次のような JDBC 呼び出しを必ず閉じてください

以下は、接続プールから取得したデータベース接続を使用する適切に記述されたコードの例です。

  Connection conn = null;
  Statement stmt = null;  // Or PreparedStatement if needed
  ResultSet rs = null;
  try {
    conn = ... get connection from connection pool ...
    stmt = conn.createStatement("select ...");
    rs = stmt.executeQuery();
    ... iterate through the result set ...
    rs.close();
    rs = null;
    stmt.close();
    stmt = null;
    conn.close(); // Return to connection pool
    conn = null;  // Make sure we don't close it twice
  } catch (SQLException e) {
    ... deal with errors ...
  } finally {
    // Always make sure result sets and statements are closed,
    // and the connection is returned to the pool
    if (rs != null) {
      try { rs.close(); } catch (SQLException e) { ; }
      rs = null;
    }
    if (stmt != null) {
      try { stmt.close(); } catch (SQLException e) { ; }
      stmt = null;
    }
    if (conn != null) {
      try { conn.close(); } catch (SQLException e) { ; }
      conn = null;
    }
  }

"

于 2011-07-13T18:23:40.977 に答える