Bug #34518 | Memory leak: StatementImpl.execute() leaks the executed sql string. | ||
---|---|---|---|
Submitted: | 13 Feb 2008 11:08 | Modified: | 25 Feb 2008 12:12 |
Reporter: | Shadow Caster | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / J | Severity: | S2 (Serious) |
Version: | OS: | Any | |
Assigned to: | Mark Matthews | CPU Architecture: | Any |
[13 Feb 2008 11:08]
Shadow Caster
[13 Feb 2008 11:12]
Tonci Grgin
Hi and thanks for your report. I think this behavior is intentional but will have to check.
[13 Feb 2008 11:37]
Shadow Caster
As it turns out, this does not happen in the default configuration. It only occurs when "useCursorFetch" is enabled.
[13 Feb 2008 13:43]
Shadow Caster
It also requires setFetchSize. To prevent that any ohter condition is missing, I have created a complete test case. You should see OutOfMemoryError within a few seconds. Additionally, increasing the size of the blob to like 100k causes the mysql server itself to start using insane amounts of memory. public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); Properties p = new Properties(); p.put("user", "root"); p.put("password", "***"); p.put("useCursorFetch", "true"); Connection c = DriverManager.getConnection( "jdbc:mysql://localhost:3306/", p); Statement s = c.createStatement(); s.execute("CREATE DATABASE memtest"); s.execute("USE memtest"); s.execute("CREATE TABLE foo (bar LONGBLOB) Engine=MyISAM"); s.close(); char[] zero = new char[1000]; Arrays.fill(zero, '0'); String sql = "INSERT INTO foo VALUES (x'" + new String(zero) + "')"; for (;;) { Statement t = c.createStatement(); t.setFetchSize(10); t.execute(sql); t.close(); } } catch (Exception exc) { exc.printStackTrace(); } }
[13 Feb 2008 13:58]
Tonci Grgin
Verified as described.
[13 Feb 2008 14:06]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/42217
[13 Feb 2008 14:14]
Mark Matthews
Because of the way cursors work in MySQL, we do have to hold onto the "internal" prepared statement until the result set is closed, so that's what this fix does. The string used for the statement will be held as well, because we have to have the ability to "re-prepare" the statement should we lose the connection. Without the original SQL, it can not be done.
[25 Feb 2008 12:12]
MC Brown
A note has been added to the 5.1.6 changelog: When using a cursor fetch for a statement, the internal prepared statement could cause a memory leak until the connection was closed. The internal prepared statement is now deleted when the corresponding result set is closed.
[27 Feb 2008 17:12]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/43086