2010-03-20 6 views
5

एक वस्तु एक विधि में घोषित पर विचार करें:विधि में घोषित वस्तु ऑब्जेक्ट रिटर्न से पहले कचरा संग्रहण के अधीन क्यों है?

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

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

से पहले foo() रिटर्न कचरा संग्रहण के अधीन किया obj होगा?

अद्यतन: इससे पहले मैंने सोचा था कि जब तक obj foo() रिटर्न कचरा संग्रहण के अधीन नहीं है।

हालांकि, आज मुझे खुद को गलत लगता है।

मैंने एक बग फिक्स करने में कई घंटे व्यतीत किए हैं और अंत में समस्या ओबीजे कचरे के कारण हुई है!

क्या कोई यह समझा सकता है कि ऐसा क्यों होता है? और अगर मैं ओबीजे को पिन करना चाहता हूं तो इसे कैसे प्राप्त किया जाए?

यहां कोड है जिसमें समस्या है।

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(); 
    } 
} 

जावा प्रोग्राम चलाने के बाद, यह निम्न संदेश प्रिंट होगा इससे पहले कि यह दुर्घटनाओं:

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

और यहाँ वर्ग 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; 
      } 
     } 
    } 
} 
+1

आप 'अंतिमकरण') में संदेश प्रिंट नहीं कर रहे हैं, तो आप इसे 'क्लोज़()' में प्रिंट कर रहे हैं, और आप 'क्लोज़()' स्वयं को कॉल कर रहे हैं। संदेश को अंतिम रूप में ले जाएं, और पुनः प्रयास करें। – skaffman

+1

आपको अपने अपडेट के लिए एक अलग प्रश्न पोस्ट करना चाहिए। –

+0

@skaffman: मुझे मुख्य से नज़दीकी() हटा देना चाहिए। समस्या अभी भी बनी हुई है। –

उत्तर

संबंधित मुद्दे