I have a method called QueryTest that queries a MySQL database over the network to get a table called output. From the start this method, when run, steadily keeps eating more memory until it eventually runs into an out of memory error. I have removed everything I can think of even putting the query in a loop with a 500ms time out but still no luck.
我有一个名为QueryTest的方法,它通过网络查询MySQL数据库以获得一个名为output的表。从一开始这个方法运行时,稳定地继续占用更多内存,直到它最终遇到内存不足错误。我已经删除了我能想到的所有内容,即使将查询放在一个500ms超时的循环中,但仍然没有运气。
The program is meant to be run on a low memory device so I cannot have it continue increasing in memory usage.
该程序应该在低内存设备上运行,所以我不能让它继续增加内存使用量。
Please see my code below. This class is called by another that only contains new Thread (new QueryTest ()).start () and has no other effect.
请参阅下面的代码。这个类被另一个只调用新的Thread(new QueryTest())。start()并且没有其他效果。
EDIT 1: If I add System.gc (); just before Thread.sleep it adds about 7mb to my program but the problem goes away. I know that method can only hint at the Garbage Collector so would this be a reliable workaround?
编辑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);
}
}
}
1 个解决方案
#1
0
Close the statements, and free the result sets when you dont need that. At the and of the loop.
关闭语句,并在不需要时释放结果集。在循环和循环。
...
rs.close(); //free result set
s.close(); //close the statement
Thread.sleep(500)
}
I had the same propbem in my java applications. Sometimes the solution i write below does not help. But after i began to use other Database Library: http://sourceforge.net/projects/c3p0/, the memory usage decreesed radically, and the application worked faster. It use persistent connection, so i recommend it only console or desktop applications, not with Java Servlet Pages.
我的java应用程序中有相同的propbem。有时我在下面写的解决方案没有帮助。但是在我开始使用其他数据库之后:http://sourceforge.net/projects/c3p0/,内存使用情况根本得到了解决,应用程序工作得更快。它使用持久连接,所以我建议只使用控制台或桌面应用程序,而不是Java Servlet Pages。
I recommend to read this topic: Java MySQL JDBC Memory Leak ;)
我建议阅读这个主题:Java MySQL JDBC内存泄漏;)
After you installed or added the C3P0 lib to your project just import:
将C3P0 lib安装或添加到项目后,只需导入:
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
After this you does not have to change your code (as i remember but you should read the manual of this lib http://www.mchange.com/projects/c3p0/apidocs/com/mchange/v2/c3p0/ComboPooledDataSource.html)
在此之后你不必更改你的代码(我记得你应该阅读这本书的手册http://www.mchange.com/projects/c3p0/apidocs/com/mchange/v2/c3p0/ComboPooledDataSource.html )
#1
0
Close the statements, and free the result sets when you dont need that. At the and of the loop.
关闭语句,并在不需要时释放结果集。在循环和循环。
...
rs.close(); //free result set
s.close(); //close the statement
Thread.sleep(500)
}
I had the same propbem in my java applications. Sometimes the solution i write below does not help. But after i began to use other Database Library: http://sourceforge.net/projects/c3p0/, the memory usage decreesed radically, and the application worked faster. It use persistent connection, so i recommend it only console or desktop applications, not with Java Servlet Pages.
我的java应用程序中有相同的propbem。有时我在下面写的解决方案没有帮助。但是在我开始使用其他数据库之后:http://sourceforge.net/projects/c3p0/,内存使用情况根本得到了解决,应用程序工作得更快。它使用持久连接,所以我建议只使用控制台或桌面应用程序,而不是Java Servlet Pages。
I recommend to read this topic: Java MySQL JDBC Memory Leak ;)
我建议阅读这个主题:Java MySQL JDBC内存泄漏;)
After you installed or added the C3P0 lib to your project just import:
将C3P0 lib安装或添加到项目后,只需导入:
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
After this you does not have to change your code (as i remember but you should read the manual of this lib http://www.mchange.com/projects/c3p0/apidocs/com/mchange/v2/c3p0/ComboPooledDataSource.html)
在此之后你不必更改你的代码(我记得你应该阅读这本书的手册http://www.mchange.com/projects/c3p0/apidocs/com/mchange/v2/c3p0/ComboPooledDataSource.html )