Why is an object declared in a method garbage collected before the method returns?

Consider the object declared in the method:

public void foo() {
    final Object obj = new Object();

    // A long run job that consumes tons of memory and 
    // triggers garbage collection
}

Will obj be a garbage collection object before foo () returns?

UPDATE : I used to think that obj is not garbage collected until foo () returns.

However, today I am mistaken.

I spent several hours fixing the error and finally found that the problem was caused by garbage collection obj!

Can anyone explain why this is happening? And if I want obj to be fixed, how to achieve it?

Here is the code that has the problem.

public class Program
{
    public static void main(String[] args) throws Exception {
        String connectionString = "jdbc:mysql://<whatever>";

        // I find wrap is gc-ed somewhere
        SqlConnection wrap = new SqlConnection(connectionString); 

        Connection con = wrap.currentConnection();
        Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
             ResultSet.CONCUR_READ_ONLY);
        stmt.setFetchSize(Integer.MIN_VALUE);

        ResultSet rs = stmt.executeQuery("select instance_id, doc_id from
               crawler_archive.documents");

        while (rs.next()) {
            int instanceID = rs.getInt(1);
            int docID = rs.getInt(2);

            if (docID % 1000 == 0) {
                System.out.println(docID);
            }
        }

        rs.close();
        //wrap.close();
    }
}

After starting the Java program, it displays the following message before the failure:

161000
161000
********************************
Finalizer CALLED!!
********************************
********************************
Close CALLED!!
********************************
162000
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 

And here is the SqlConnection class code:

class SqlConnection
{
    private final String connectionString;
    private Connection connection;

    public SqlConnection(String connectionString) {
        this.connectionString = connectionString;
    }

    public synchronized Connection currentConnection() throws SQLException {
        if (this.connection == null || this.connection.isClosed()) {
            this.closeConnection();
            this.connection = DriverManager.getConnection(connectionString);
        }
        return this.connection;
    }

    protected void finalize() throws Throwable {
        try {
            System.out.println("********************************");
            System.out.println("Finalizer CALLED!!");
            System.out.println("********************************");
            this.close();
        } finally {
            super.finalize();
        }
    }

    public void close() {
        System.out.println("********************************");
        System.out.println("Close CALLED!!");
        System.out.println("********************************");
        this.closeConnection();
    }

    protected void closeConnection() {
        if (this.connection != null) {
            try {
                connection.close();
            } catch (Throwable e) {
            } finally {
                this.connection = null;
            }
        }
    }
}
+5
source share
7

, , "wrap", , "wrap" .

, , , , , , :

SqlConnection wrap = new SqlConnection(connectionString); 
Connection con = wrap.currentConnection();

:

Connection con = new SqlConnection(connectionString).currentConnection();

( ), "" . GC .

, .

+3

, . , :

public class GcTest {

    public static void main(String[] args) {
        System.out.println("Starting");

        Object dummy = new GcTest(); // gets GC'd before method exits

        // gets bigger and bigger until heap explodes
        Collection<String> collection = new ArrayList<String>();

        // method never exits normally because of while loop
        while (true) {
            collection.add(new String("test"));
        }
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("Finalizing instance of GcTest");
    }
}

:

Starting
Finalizing instance of GcTest
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2760)
    at java.util.Arrays.copyOf(Arrays.java:2734)
    at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
    at java.util.ArrayList.add(ArrayList.java:351)
    at test.GcTest.main(GcTest.java:22)

, , .

, , VM , , . .

, finalize(), , .

+5

. obj - , Object, Object . ( ).

, Object . , , GC.

EDIT: Java (. JVM) ( , ). .

EDIT: ,

+2

, , Java Garbage Collection Finialization . , , wrap . , , wrap GC, ( wrap ). , JVM (, HotSpot -server) , , GC, . , , .

, , , SqlConnection . , SqlConnection . Connection .

+1

obj foo()?

, obj , foo , , , , foo.

- , ?

GC . , foo.

. , obj , foo , . .

+1

obj - , , . Object , , , . Object GC'd , obj , .. .


EDIT: ,

UPDATE: Let me make the question more clear. 
Will obj be subject to garbage collection before foo() returns?

obj - . obj foo(). , Will obj be subject to garbage collection before foo() returns? , obj , foo() , .

0

- , . , , , , , , . , .

, .

0

All Articles