5

NetBeans プロファイラーで、クエリを実行した後、Surviving Generations が増加し続けることを確認しました。

@Select("SELECT * FROM ais_dynamic WHERE rep_time >= #{from} AND rep_time <= #{to} AND ais_system = #{sys}")    
@Options(useCache=false,fetchSize=8192)
List<AisDynamic> getRecords(
        @Param("from") Timestamp from,
        @Param("to") Timestamp to,
        @Param("sys") int sys);

リストにあるオブジェクトは、他の場所では使用されていないにもかかわらず解放されず、クエリを実行してその結果を処理するバックグラウンド スレッドで停止するかのようです。

以下は、NetBeans プロファイラーによって返されたライブ結果です。 NetBeans プロファイラーからのライブ結果

私の質問:

  1. どうすればメモリリークを防ぐことができますか?
  2. このクエリを最適化するにはどうすればよいOptionsですか?

何か必要な場合は、何を教えてください。提供します。

アップデート:

さらにテストを重ねた結果、取得した結果への参照を保持している MyBatis に問題があるため、時間の経過とともにガベージ コレクションが行われないことが懸念されます。クエリを 20 回呼び出してから待機した後、30 分経ってもガベージ コレクションが発生しません。私がすることは、メソッドを呼び出すことだけです:List<AisDynamic> adList = mapper.getRecords(from, to, sys);

4

1 に答える 1

3

週末にテストしたところ、問題が解決したようです。提案してくれた@partlovに感謝しますが、それは解決策ではありませんが、問題を再度テストする必要があり、実際の問題を発見しました。

問題は、ユーザーからのクエリ要求の処理を担当するクライアントが (クエリを実行していた) スレッドを積み上げていたことです。run()クライアントをストレステストしたときにリクエストが非常に頻繁に来ていたので、前のクエリが実行されなかったときに、クエリのメソッド内でフラグを設定およびチェックしてキャンセルしていたにもかかわらず、次のクエリが開始されていました。これは、クエリのセッションがまだデータベースと通信している場合に発生していました。たとえば、select に 30k 以上の結果があった場合などです。したがって、キャンセル フラグが立てられていても、クエリがデータベースから結果を取得している最中だったため、まだチェックされていませんでした。これは、次のクエリを開始するのに十分な時間だったので、結果が多数ある場合、クライアントはスレッドを積み上げて、より多くのメモリを消費していました。

データベースと通信するセッション (選択クエリなど) をキャンセルする方法は (私が知っている限りでは) ないように思われるので、それを防ぐMyBatisメカニズムを自分で実装する必要がありました。クライアントに実装したメカニズムにより、前の (同じユーザーに対して実行された) クエリが終了するまで、次のクエリが開始されないことが保証されます。したがって、クエリはクライアントがrun()メソッドを終了したときにクライアントに通知し、その後で初めて同じユーザーの次のクエリが開始される可能性があります。


更新私は経験から、長い取得トランザクションを中止/キャンセルする唯一の少し汚れた方法 (私の好みによる) は、トランザクションが使用するインスタンスclose()のメソッドを呼び出すことであることを学びました。SqlSessionこれにより、意図したとおりにキャッチして処理する必要がある例外 (以下の例) が発生します。

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.NullPointerException
### The error may exist in YourMapper.java (best guess)
### The error may involve methodOfTheHandlerInvolved
### The error occurred while handling results
### SQL: sqlOfYourQuery
### Cause: java.lang.NullPointerException
... (and a trace follows) ...
于 2013-04-25T15:50:33.947 に答える