2

ネットワーク経由で MySQL データベースにクエリを実行して、output というテーブルを取得する QueryTest というメソッドがあります。最初からこのメソッドを実行すると、最終的にメモリ不足エラーが発生するまで、着実にメモリを消費し続けます。500ミリ秒のタイムアウトでクエリをループに入れることさえ考えられるすべてを削除しましたが、それでもうまくいきません。

このプログラムはメモリの少ないデバイスで実行することを意図しているため、メモリ使用量を増やし続けることはできません。

以下の私のコードを見てください。このクラスは、new Thread (new QueryTest ()).start () のみを含む別のクラスによって呼び出され、他の効果はありません。

編集 1: System.gc (); を追加すると Thread.sleep の直前にプログラムに約 7MB 追加されますが、問題は解消されます。メソッドがガベージコレクターを示唆することしかできないことを知っているので、これは信頼できる回避策でしょうか?

// Add the main package
package DBTest;


// Import List
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;


public class QueryTest implements Runnable
{
    // Constant Objects
    public static Connection connection = null;
    ResultSet rs;
    ResultSetMetaData rsmd;
    Statement s;


    // Variables
    int portA = 0;
    int size = 0;
    String outputs [][] = new String [0][5];
    boolean isRunning = true;
    boolean isPaused = false;



    // The main method for starting the thread
    public void run ()
    {       
        // Try to connect to the database and query the updates
        try
        {       
            // Load the database driver
            Class.forName("com.mysql.jdbc.Driver").newInstance();       

            // Connect to the database
            connection = DriverManager.getConnection ("jdbc:mysql://192.168.1.103/noah", "root", "0004e5dcb6a");
            System.out.println ("Connection Made");

            // let the loop run while the thread is allowed to run
            while (isRunning)
            {       
                // Query the database if the thread is not paused
                if (!isPaused)
                {
                    // Create a prepared statement
                    s = connection.createStatement ();

                    // Execute the query and store the results
                    rs =  s.executeQuery ("SELECT * FROM outputs");

                    // Get the result set meta data
                    rsmd = rs.getMetaData();

                    // Set the result set to the last row
                    rs.last();

                    // Get the last row number
                    size = rs.getRow();

                    // Set the result set to the last row
                    rs.first();

                    /*// Get port A values
                    for (int a = 0; a < 8; a ++)
                    {
                        // Check if the output is active
                        if (Integer.parseInt(outputs [a][4]) == 1)
                        {
                            // Add to the port
                            portA = portA + Integer.parseInt (outputs [a][3]);
                            System.out.println (portA);
                        }
                    }*/

                    // Set the value of portA
                    portA = 0;
                }

                // Let the thread sleep
                Thread.sleep (500);
            }   

            // Close the connection
            connection.close();
            System.out.println ("Connection Closed");   
        }

        // Catch a error
        catch (Exception queryDatabaseErr)
        {
            System.out.println (queryDatabaseErr);
        }
    }
}
4

1 に答える 1

1

ステートメントを閉じ、不要な場合は結果セットを解放します。ループのとこで。

    ...
    rs.close();  //free result set
    s.close();   //close the statement
    Thread.sleep(500)
}

私のJavaアプリケーションにも同じ問題がありました。以下に書いた解決策が役に立たないことがあります。しかし、他のデータベース ライブラリを使用し始めた後: http://sourceforge.net/projects/c3p0/、メモリ使用量が大幅に減少し、アプリケーションの動作が速くなりました。永続的な接続を使用するため、Java サーブレット ページではなく、コンソールまたはデスクトップ アプリケーションのみをお勧めします。

このトピックを読むことをお勧めします: Java MySQL JDBC Memory Leak ;)

プロジェクトに C3P0 lib をインストールまたは追加したら、以下をインポートします。

import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

この後、コードを変更する必要はありません (私が覚えているように、このライブラリのマニュアルを読む必要がありますhttp://www.mchange.com/projects/c3p0/apidocs/com/mchange/v2/c3p0/ComboPooledDataSource.html )

于 2013-03-30T12:23:10.493 に答える