2017-07-24 114 views
3

我有一個靜態方法,我用它來處理ResultSets並讓它返回一個對象。有時它會一次又一次地被調用。例如,在我正在處理的當前項目中,靜態方法被調用超過56,000次。無論出於何種原因,隨着它一遍又一遍地被調用,該方法需要更長和更長的時間來回復。爲什麼這種靜態方法需要更長時間才能完成?

我一直在使用System.currentTimeMillis()找出其中的代碼也越拉越長就完成了,雖然我知道currentTimeMillis()不是100%準確的,它需要時間慢慢完成這部分代碼並且會隨着時間而反覆增加。

下面是代碼:

public static Object createFromResultSet(ResultSet someResultSet, String someIndex) throws SQLException, Exception { 
    { ... } 
    List<Object[]> result = new ArrayList(); 
    List<String> columnNames = new ArrayList(); 
    List<Object> addRow; 

    // the code below will take longer and longer to complete as the method is called over and over again 
    while (someResultSet.next()) { 
     addRow = new ArrayList(); 
     for (int x = 0; x < columnNames.size(); x++) { 
      if (someResultSet.getObject(x + 1) instanceof Double) { 
       Double someValue = someResultSet.getDouble(x + 1); 
       addRow.add(new BigDecimal(someValue).toPlainString()); 
      } 
      else if (someResultSet.getObject(x + 1) != null) addRow.add(someResultSet.getObject(x + 1).toString()); 
      else addRow.add(""); 
     } 
     result.add(addRow.toArray()); 
    } 
    { ... } 
} 

也許我不完全瞭解的靜態方法在Java中的工作,但我認爲,在這個方法中的所有變量將僅一次的時間,即內使用調用靜態方法(即,如果再次調用該方法,則從前一次調用該方法時沒有值被繼承)。除了正在傳入的變量之外,沒有正在使用的靜態變量在方法外聲明。但是,隨着時間的推移,該方法變得越來越慢,導致我相信有以前調用此方法時使用的數據。在我當前項目中調用的56,000次中,該報告可能需要一個小時才能運行。

東西告訴我我的邏輯有問題,但對於我這樣的人來說,我不知道發生了什麼。

+1

*理論:*你不釋放你的資源(內存泄漏),並且系統花費越來越多的時間做GC運行。 – Andreas

+0

@Andreas讓我們說你是對的。如何以自己的GC語言釋放資源? –

+0

當你知道數組的大小('columnNames.size()')時,你爲什麼要給'ArrayList'增加值,最後調用'toArray()'?用'Object [] row = new Object [columnNames.size()];'替換'addRow = new ArrayList();'。使用'ArrayList'會產生不必要的垃圾。 – Andreas

回答

-1

只是由於內存變滿而發生這種情況。 你應該做的三件事情:

  1. 讓他們全球性的。這樣每個方法出口都不會有GC調用。內存將只被分配一次,不會發生重定位 - 分配。

    List<Object[]> result; 
    List<String> columnNames; 
    List<Object> addRow; 
    
  2. 在「createFromResultSet」方法的末尾,清除這些列表。例如:

    addRow.clear(); 
    
  3. 創建「addRow = new ArrayList();」在宣言本身。

    List<Object> addRow = new ArrayList(); 
    
+0

清除即將離開作用域的集合完全沒有任何作用。不要將代碼格式設置爲不是代碼的文本。 – EJP

+0

EJP感謝格式化。也請閱讀所有三個步驟。將它們作爲全局變量時,將需要清除。如果沒有閱讀完整的文字,請不要低估。 – Aman

相關問題