0

このコードのメモリ リークはどこにありますか? この関数は、大量のメモリを使用して何百万回も実行され、240 万回の実行後にメモリ不足の例外が発生します。

public static void saveCall(Call call) {
        conn = getInstance();

        if (conn != null) {
            try {
                calendar.setTime(call.getDate());
                String sql = "INSERT INTO Calls(id, datetime, duration, customer_phone_id, partner_phone_id) "
                        + "VALUES(null, ?, ?, ?, ?)";
                PreparedStatement preparedStatement = conn
                        .prepareStatement(sql);
                preparedStatement.setString(1, dateFormat.format(calendar.getTime()));
                preparedStatement.setLong(2, call.getDuration());
                preparedStatement.setLong(3, call.getPhone().getPhoneNumber());
                preparedStatement.setLong(4, call.getPhonePartner()
                        .getPhoneNumber());

                preparedStatement.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
4

3 に答える 3

1

プログラムが大量のメモリを使用する場合、リークは発生せず、ガベージ コレクタの問題のみが発生する可能性があります。IE、ガベージが遅すぎて、新しいオブジェクトを作成するためのスペースを解放できませんでした。

ここから、クエリを実行するときにコードをプロファイリングすることができます (visualvm または任意の jdk で提供される jconsole)。メモリ空間がどのように満たされているかがわかります (ガベージ ビヘイビアとオブジェクト サイズ)。

次に、必要に応じて、jvm ガベージ コレクションを構成する必要があります。 詳細なドキュメントは次のとおりです 。http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.htmlプロファイル、構成を支援する場合があります。

EDIT:メモリリークがあり、私は間違っていました;-)

于 2013-05-19T21:30:44.530 に答える
0

@Pascal Bayer : SQL 操作の後に接続を閉じる必要があります。close() を使用して変更されたコードは、次のようになります。

public static void saveCall(Call call) {
        conn = getInstance();

        if (conn != null) {
            try {
                calendar.setTime(call.getDate());
                String sql = "INSERT INTO Calls(id, datetime, duration, customer_phone_id, partner_phone_id) "
                        + "VALUES(null, ?, ?, ?, ?)";
                PreparedStatement preparedStatement = conn
                        .prepareStatement(sql);
                preparedStatement.setString(1, dateFormat.format(calendar.getTime()));
                preparedStatement.setLong(2, call.getDuration());
                preparedStatement.setLong(3, call.getPhone().getPhoneNumber());
                preparedStatement.setLong(4, call.getPhonePartner()
                        .getPhoneNumber());

                preparedStatement.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
              // good practice of closing connections as soon as 
              // the SQL operations are       completed
              if(!conn.isClosed())
                conn.close();
            }
        }
}

乾杯、マドゥ。

于 2013-05-19T21:59:29.207 に答える