db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Noll <dan...@nuix.com.au>
Subject Re: Garbage Collector and memory
Date Tue, 25 Oct 2005 03:23:56 GMT
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.


Mime
View raw message