我有一个名为 QueryTest 的方法,它通过网络查询 MySQL 数据库以获得一个名为 output 的表。从一开始,此方法在运行时会稳定地消耗更多内存,直到最终遇到内存不足错误。我已经删除了我能想到的所有内容,甚至将查询置于超时为 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);
}
}
}
最佳答案
关闭语句,并在不需要时释放结果集。在循环的 and 处。
...
rs.close(); //free result set
s.close(); //close the statement
Thread.sleep(500)
}
我的 java 应用程序中有相同的问题。有时我在下面写的解决方案没有帮助。但是在我开始使用其他数据库库之后:http://sourceforge.net/projects/c3p0/ ,内存使用量急剧下降,应用程序运行速度更快。它使用持久连接,所以我建议只使用控制台或桌面应用程序,而不是使用 Java Servlet 页面。
我建议阅读此主题:Java MySQL JDBC Memory Leak ;)
将 C3P0 库安装或添加到项目后,只需导入:
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 )
关于mysql - Java MySQL查询线程不断增加内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15718459/