[java] メモリリークを防ぐため、JDBCドライバは強制的に登録解除されています



Answers

サーブレット・コンテキスト・リスナーのcontextDestroyed()メソッドで、ドライバを手動で登録解除します。

        // This manually deregisters JDBC driver, which prevents Tomcat 7 from complaining about memory leaks wrto this class
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                LOG.log(Level.INFO, String.format("deregistering jdbc driver: %s", driver));
            } catch (SQLException e) {
                LOG.log(Level.SEVERE, String.format("Error deregistering driver %s", driver), e);
            }

        }
Question

Webアプリケーションを実行すると、このメッセージが表示されます。 正常に動作しますが、シャットダウン中にこのメッセージが表示されます。

重大度:WebアプリケーションがJBDCドライバ[oracle.jdbc.driver.OracleDriver]を登録しましたが、Webアプリケーションが停止したときにその登録を解除できませんでした。 メモリリークを防ぐため、JDBCドライバは強制的に登録解除されています。

どんな助けもありがたい。




Mavenビルドからこのメッセージを受け取っている場合は、JDBCドライバのスコープを変更して、libディレクトリにコピーしてください。 このような:

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.18</version>
  <!-- put a copy in /usr/share/tomcat7/lib -->
  <scope>provided</scope>
</dependency>






私は同様の問題を抱えていましたが、Tomcatサーバーを実行してJSPページを変更/保存したときにいつでもJavaヒープスペースエラーが発生していたため、コンテキストが完全に再充電されませんでした。

私のバージョンはApache Tomcat 6.0.29とJDK 6u12でした。

URL http://wiki.apache.org/tomcat/MemoryLeakProtectionの Referencesセクションにあるように、JDKを6u21にアップグレードすると、JDBCドライバのエラーは引き続き表示されますが、Javaヒープスペースの問題が解決されました(コンテキストは再ロードされます)。




私はGrailsアプリケーションをAWSにデプロイしていたときにこの問題に直面しました。 これはJDBCのデフォルトドライバorg.h2ドライバの問題です。 あなたが設定フォルダ内のDatasource.groovyでこれを見ることができます。 以下に見られるように:

dataSource {
    pooled = true
    jmxExport = true
    driverClassName = "org.h2.Driver"   // make this one comment
    username = "sa"
    password = ""
}

そのデータベースを使用していない場合は、datasource.groovyファイルにorg.h2.Driverが記述されている場所にコメント行を付けます。 それ以外の場合は、そのデータベースのjarファイルをダウンロードする必要があります。

ありがとう。




アプリ(tomcat6)を削除するとそれが解決されます。 confファイルは保存されます。 それは何とか自分自身を壊す。 私はそれがどのようにそれをするのか本当にわからない。




私はこの問題がたくさん出てくるのを見ている。 はい、Tomcat 7は自動的に登録を解除しますが、本当にあなたのコードと良いコーディング方法を制御していますか? 確かに、すべてのオブジェクトを閉じ、データベース接続プールのスレッドをシャットダウンし、すべての警告を取り除くための正しいコードがすべてあることを知りたい。 私は確かにしています。

これが私のやり方です。

手順1:リスナーを登録する

web.xml

<listener>
    <listener-class>com.mysite.MySpecialListener</listener-class>
</listener>

ステップ2:リスナーを実装する

com.mysite.MySpecialListener.java

public class MySpecialListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // On Application Startup, please…

        // Usually I'll make a singleton in here, set up my pool, etc.
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // On Application Shutdown, please…

        // 1. Go fetch that DataSource
        Context initContext = new InitialContext();
        Context envContext  = (Context)initContext.lookup("java:/comp/env");
        DataSource datasource = (DataSource)envContext.lookup("jdbc/database");

        // 2. Deregister Driver
        try {
            java.sql.Driver mySqlDriver = DriverManager.getDriver("jdbc:mysql://localhost:3306/");
            DriverManager.deregisterDriver(mySqlDriver);
        } catch (SQLException ex) {
            logger.info("Could not deregister driver:".concat(ex.getMessage()));
        } 

        // 3. For added safety, remove the reference to dataSource for GC to enjoy.
        dataSource = null;
    }

}

コメントしたり、追加したり...




Related