2012-09-13 91 views
1

我有以下程序到數據庫並獲取值,我已經執行查詢也它只給我47行,但是當我在控制檯模式下運行相同的程序它給我Exception in thread "main" java.lang.OutOfMemoryError: Java heap space如何解決這個OutOfMemoryError:Java堆空間

package com.common; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.Timestamp; 
import java.sql.Types; 
import java.util.HashMap; 
import java.util.LinkedHashMap; 
import java.util.Map; 

import com.common.Query; 

public class GetColumnValuesFromDifferentTypes { 
@SuppressWarnings("unused") 
public static void printColumns(String query){ 
    ABIDAO abidao = new ABIDAO(); 
    int numberOfColumns=0,columnType = 0; 
    String columnValue = "", columnName = ""; 
    Map<String, String> headerMap = new LinkedHashMap<String, String>(); 
     Connection connection = abidao.getConnection(); 
     if (connection != null) { 
      try { 
       headerMap = getHeader(query); 
       System.out.println("===================================================================="); 
       System.out.println("Header Map : "+headerMap); 
       System.out.println("===================================================================="); 
       PreparedStatement reportTablePS = connection.prepareStatement(query); 
       ResultSet reportTable_rst = reportTablePS.executeQuery(); 
       ResultSetMetaData reportTable_rsmd = reportTable_rst.getMetaData(); 
       numberOfColumns = reportTable_rsmd.getColumnCount(); 

        int i =0; 
        while (reportTable_rst.next()) { 
          for (int columnIterator = 1; columnIterator <= numberOfColumns; columnIterator++) { 
           columnValue = null; 
           columnName = reportTable_rsmd.getColumnName(columnIterator); 
           columnType = reportTable_rsmd.getColumnType(columnIterator); 

           if(columnType == Types.CHAR || columnType == Types.VARCHAR || columnType == Types.LONGVARCHAR) 
           { 
            columnValue = reportTable_rst.getString(columnName); 
           }else if(columnType == Types.INTEGER || columnType == Types.BIGINT || columnType == Types.SMALLINT || columnType == Types.NUMERIC) 
           { 
            long templong = reportTable_rst.getLong(columnName); 
            if(!reportTable_rst.wasNull()) 
            { 
             columnValue = Long.toString(templong); 
            } 
           }else if(columnType == Types.DECIMAL || columnType == Types.DOUBLE || columnType == Types.FLOAT || columnType == Types.REAL) 
           { 
            double tempDouble1 = reportTable_rst.getDouble(columnName); 
            if(!reportTable_rst.wasNull()) 
            { 
             columnValue = Double.toString(tempDouble1); 
            } 
           } else if(columnType == Types.TIME || columnType == Types.TIMESTAMP || columnType == Types.DATE) 
           { 
            Timestamp sqlTimeStamp = reportTable_rst.getTimestamp(columnName); 
            if(!reportTable_rst.wasNull()) 
            { 
             columnValue = sqlTimeStamp.toString(); 
            } 
           } 
           System.out.println("columnValue : "+columnValue); 
           System.out.println(","); 

          } 
          System.out.println("===================================================================="); 
         } 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      }finally { 
       try { 
        abidao.closeConnection(connection, null, null); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
     } 
} 
@SuppressWarnings({ "unused" }) 
public static Map<String, String> getHeader(String query) { 
    ABIDAO abidao = new ABIDAO(); 
    String columnName=""; 
    int numberOfColumns=0,rowCount=1; 
    Map<String, String> headerNamesMap = new LinkedHashMap<String, String>(); 
    Connection connection = abidao.getConnection(); 
    if (connection != null) { 
     try { 
      PreparedStatement reportTablePS = connection.prepareStatement(query); 
      ResultSet reportTable_rst = reportTablePS.executeQuery(); 
      ResultSetMetaData rsmd = reportTable_rst.getMetaData(); 
      numberOfColumns = rsmd.getColumnCount(); 
      headerNamesMap.put("SNO","SNO"); 
       while (reportTable_rst.next()) { 
       for (int i = 1; i <= numberOfColumns; i++) { 
        columnName = rsmd.getColumnName(i).toUpperCase(); 
        if(!headerNamesMap.containsKey(columnName)){ 
         headerNamesMap.put(columnName, columnName); 
        } 
       } 
       rowCount++; 
       } 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     }finally { 
      try { 
       abidao.closeConnection(connection, null, null); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 
    return headerNamesMap; 
} 
@SuppressWarnings("rawtypes") 
public static void main(String[] args) { 
    String query = ""; 
    Map dynamicQueryMap = new HashMap(); 
    Query queryObj = new Query(); 

    try { 
     dynamicQueryMap = queryObj.getComplexReportQuery(); 
     if(dynamicQueryMap.containsKey("query")) query = dynamicQueryMap.get("query").toString(); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    printColumns(query); 

} 
} 

這是從查詢方法返回查詢:

select 
pi.po_number,poi.unit_cost,pi.placed_date CreateDate, 
case when isnull(pi.date_closed) then pi.scheduled_arrival_date 
else pi.date_closed end as ReceviedDate, 
poi.order_quantity,poi.roll_number,p.product_sku product_name, 
pc.product_category_name,poi.rec_vendor_quantity,pv.vendor_name,p.et_conversion_unit_quantity,pi.note 
from 
purchase_order as pi, 
purchase_order_inventory as poi, 
product_vendors as pv, 
products AS p, 
product_categories AS pc 
where 
pi.purchase_order_id=poi.purchase_order_id and 
pc.product_category_id=p.product_category_id and 
poi.product_id = p.product_id and 
poi.product_category_id=pc.product_category_id and 
pi.vendor_id=pv.product_vendor_id and 
((pi.date_closed >= '2012-01-01' and pi.date_closed <='2012-09-05 23:59:59') 
or (pi.scheduled_arrival_date >= '2012-01-01' and pi.scheduled_arrival_date <='2012-09-05 23:59:59')) and 
pi.po_type=0 
and pi.status_id = 0 and poi.transaction_type = 0 
order by pi.po_number ; 

什麼是我面臨的問題就在這裏!請幫我找出答案。

+0

我已經關閉的ResultSet,preparestament,連接等,甚至設置這個' -Xms64m -Xmx256m'但我仍然是相同的。 :( –

+0

請當你運行你的應用程序時顯示類路徑,以及'queryObj.getComplexReportQuery()'做什麼; 返回多少數據量? – user1516873

+1

感謝球員我想出了問題,它實際上沒有在查詢中設置條件,對於浪費你所有的時間感到抱歉。'感謝你的一些輸入' –

回答

8

您需要關閉所有資源,而不僅僅是連接。例如PreparedStatement.close()和ResultSet.close()如果你不這樣做,它們將被保留併成爲內存泄漏的一種形式。

我建議您自己使用jmap -histo:live {pid}或使用像VisualVM或YourKit這樣的內存分析器來確認。

+3

注意:關閉語句也應該關閉它的'ResultSet',但我還沒有看到依賴這個的Java代碼。 docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#close() –

+0

我已關閉resultset,preparestament,連接等,甚至設置此-Xms64m -Xmx256m,但我仍然得到同樣的:( –

+0

)在這種情況下,您需要使用內存分析器來查看您使用內存的位置,現在256M並不是那麼多,我可以將它設置爲4g。 –

1

您應該關閉連接,還應該關閉ResultSet和語句以避免內存泄漏。

並且不要忘記在再次使用它們之前關閉語句和其他資源。

Statement stmt = ...; 
... 
stmt.close(); 
stmt = ... 
1

避免了程序化的錯誤,以節省更多的內存後,可以嘗試改變你的JVM的配置設置您的應用程序的特定堆大小。看看這篇文章:http://informix-zone.com/node/46

1

堆大小還取決於數據庫配置文件中定義的共享緩衝區 您必須增加數據庫配置文件中的共享緩衝區大小。

對於監控堆,您可以使用監控工具: -

  • JMAP

  • jmonitor

相關問題