捕获到`OutOfMemoryException`时将触发`GC`吗?

时间:2019-02-21 03:18:12

标签: java java-8 garbage-collection out-of-memory

我有一个Java程序包,该程序包与数据库连接并获取一些数据。在极少数情况下,由于获取的查询数据大小超出了Java堆空间,因此我遇到了堆内存异常。现在,企业无法考虑增加Java堆空间。

其他选项是捕获异常并继续执行流程以停止执行。 (我知道捕获OOME不是一个好主意,但在这里只有我自己的局部变量会受到影响)。我的代码如下:

private boolean stepCollectCustomerData() {
     try {          
          boolean biResult = generateMetricCSV(); 
     } catch (OutOfMemoryError e) {         
        log.error("OutOfMemoryError while collecting data ");            
        log.error(e.getMessage());      
        return false; 
     }
        return true;
    }

private boolean generateMetricCSV(){

        // Executing the PAC & BI cluster SQL queries.
        try (Connection connection = DriverManager.getConnection("connectionURL", "username", "password")) {

            connection.setAutoCommit(false);
            for (RedshiftQueryDefinition redshiftQueryDefinition: redshiftQueryDefinitions){
                File csvFile = new File(dsarConfig.getDsarHomeDirectory() + dsarEntryId, redshiftQueryDefinition.getCsvFileName());
                log.info("Running the query for metric: " + redshiftQueryDefinition.getMetricName());
                try( PreparedStatement preparedStatement = createPreparedStatement(connection,
                        redshiftQueryDefinition.getSqlQuery(), redshiftQueryDefinition.getArgumentsList());
                     ResultSet resultSet = preparedStatement.executeQuery();
                     CSVWriter writer = new CSVWriter(new FileWriter(csvFile));) {

                    if (resultSet.next()) {
                        resultSet.beforeFirst();
                        log.info("Writing the data to CSV file.");
                        writer.writeAll(resultSet, true);
                        log.info("Metric written to csv file:  " + csvFile.getAbsolutePath());
                        filesToZip.put(redshiftQueryDefinition.getCsvFileName(), csvFile);
                    } else {
                        log.info("There is no data for the metric " + redshiftQueryDefinition.getCsvFileName());
                    }
                } catch (SQLException | IOException e) {
                    log.error("Exception while generating the CSV file: " + e);
                    e.printStackTrace();
                    return false;
                }
            }
        }  catch (SQLException e){
            log.error("Exception while creating connection to the Redshift cluster: " + e);
            return false;
        }
        return true;
    }

在后面的方法中,"ResultSet resultSet = preparedStatement.executeQuery()"行中出现异常,而我在父方法中捕获了此异常。现在,我需要确保在前一种方法中捕获到异常时,GC是否已触发并清除了局部变量内存? (例如连接和结果集变量),否则,什么时候发生?

我担心Java堆空间,因为这是连续不断的,我需要继续为其他用户获取数据。

我提供的代码仅用于解释潜在的问题和流程,请友好地忽略语法等。我正在使用JDK8

谢谢。

0 个答案:

没有答案