Juan Ignacio Villa wrote:
Hello.
My java application uses memory more and more until it
crash. It is strange because not use new variables nor
I do not create them dynamically. I have an for with
which I make select SQL by means of inserted dynamic
values. The peculiar thing is that in each return of
for for, the program uses memory more and more, but I
do not create new variables, but reusing same
variables. I proved to garbage it with runtime.gc but
there was no difference. Dont free it.
There are a number of things going on here.
As it says in the Java documentation, Runtime.gc() is not guaranteed to
do anything in the first place. Use of the call is usually a sign of
bad code.
The used memory comes from another part?
If you run this code twice in a row, does the total used memory
increase? If it doesn't, then it may just be Derby's cache taking up
the memory.
If you get an OutOfMemoryError then obviously there is a real problem.
But if you're getting a crash, then there might be some other problem,
perhaps related to the specific JVM you're running.
My code is:
Class.forName"org.apache...");
java.sql.Connection DbConexion =
DriverManager.getConnection("jdbc:derby:" + addpath
+"/prueba....");
String sql ="";
Statement Consulta =null;
ResultSet Rs = null;
for (int i=1; i<400; i++) {
sql="SELECT * FROM tipo2 WHERE " + consul[i];
Consulta =
DBConexion.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
Rs = Consulta.executeQuery(sql);
Rs.close();
Rs = null;
Consulta.close();
Consulta = null;
}
try{
Rs.close();
Consulta.close();
Rs = null;
Consulta = null;
}catch(...)
There are a number of issues with the above code, but fixing the issues
wouldn't necessarily fix this issue anyway. Ignoring the code style for
now (variables start with a lower-case letter, references don't need to
be assigned to null a few nanoseconds before they're about to be
assigned to again, etc.), the code above is extremely bad at handling
bad conditions.
Written properly, the code above would look more like:
Statement statement =
connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCURT_UPDATABLE);
try {
for (int i = 1; i < 400; i++) { // <-- looping from 1 to 399 is
weird in itself.
String sql = ...
ResultSet rs = statement.executeQuery(sql);
try {
// Do stuff with rs.
} finally {
try {
rs.close();
} catch (SQLException e) { /* ignore or log */ }
}
}
} finally {
try {
statement.close();
} catch (SQLException e) { /* ignore or log */ }
}
The reason for the use of finally here is that if your code on the
inside threw an exception, then nothing would have been closed. That
would be guaranteed to cause memory leaks like what you describe, but
only in the event of errors.
And of course, this reuses the same statement, because creating multiple
statements when you only actually need one is wasteful.
Daniel
--
Daniel Noll
NUIX Pty Ltd
Level 8, 143 York Street, Sydney 2000
Phone: (02) 9283 9010
Fax: (02) 9283 9020
This message is intended only for the named recipient. If you are not
the intended recipient you are notified that disclosing, copying,
distributing or taking any action in reliance on the contents of this
message or attachment is strictly prohibited.