我有以下程序进入数据库并获取值,我已经执行了查询,它也只给了我47行,但是当我在控制台模式下运行相同的程序时,它给了我Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
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);
}
}
这是从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 :(得分:8)
您需要关闭所有资源,而不仅仅是连接。例如PreparedStatement.close()和ResultSet.close()如果不这样做,它们将被保留并成为内存泄漏的一种形式。
我建议您使用jmap -histo:live {pid}
或使用VisualVM或YourKit等内存分析器自行确认。
答案 1 :(得分:1)
您应该关闭Connection以及ResultSet和Statements以避免内存泄漏。
在再次使用它们之前不要忘记关闭语句和其他资源。
Statement stmt = ...;
...
stmt.close();
stmt = ...
答案 2 :(得分:1)
在避免编程错误以节省更多内存之后,您可以尝试通过更改JVM的配置来为应用程序设置特定的堆大小。看一下这篇文章:http://informix-zone.com/node/46
答案 3 :(得分:1)
堆大小还取决于数据库配置文件中定义的共享缓冲区 您必须在数据库配置文件中增加共享缓冲区大小。
对于监控堆,您可以使用监控工具: -
JMAP
jmonitor