Consider an object declared in a 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 subject to garbage collection before foo() returns?
UPDATE: Previously I thought obj is not subject to garbage collection until foo() returns.
However, today I find myself wrong.
I have spend several hours in fixing a bug and finally found the problem is caused by obj garbage collected!
Can anyone explain why this happens? And if I want obj to be pinned how to achieve it?
Here is the code that has 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 running the Java program, it will print the following message before it crashes:
161000
161000
********************************
Finalizer CALLED!!
********************************
********************************
Close CALLED!!
********************************
162000
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 
And here is the code of class SqlConnection:
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;
            }
        }
    }
}