如何解决java中的堆栈内存溢出错误

时间:2016-02-23 11:51:07

标签: java

我正在创建一个实用程序来调用Web服务,该服务根据当前日期从数据库中检索数据。为此我创建了一个service()方法,如果在当前日期将任何新数据插入到数据库中,则会递归调用。但该代码将在一段时间后通过堆栈溢出错误

package com.RMCServices;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import dbconnection.DbCon;

public class SimpleThreadPoolRMC {



    public SimpleThreadPoolRMC() {
        processCommand();
        try {
            finalize();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Service();
    }

    public void Service(){
        Connection con=null;
        con=DbCon.getConnection();
        PreparedStatement ps1=null,ps2=null;
        ResultSet rs1=null,rs2=null;
        String phone_no=null;
        try {
            ps1=con.prepareStatement("SELECT MAX(d.id) AS id,d.Batch_No,d.tcontractor_id,d.twork_id,d.Batch_Time,d.Production_Qty,SUM(d.Gate1_Actual)AS Gate1_Actual,SUM(d.Gate2_Actual) AS Gate2_Actual,SUM(d.Gate3_Actual) AS Gate3_Actual,SUM(d.Gate4_Actual) AS Gate4_Actual,SUM(d.Cement1_Actual) AS Cement1_Actual,SUM(d.Water1_Actual) AS Water1_Actual,SUM(d.Adm1_Actual1) AS Adm1_Actual1,SUM(d.Adm2_Actual1) AS Adm2_Actual1,r.Truck_No,r.Recipe_Name FROM tr_rmc_batch_details AS d,tr_rmc_batch AS r WHERE d.tContractor_Id=r.tContractor_Id AND d.tWork_Id=r.tWork_Id AND d.tPlant_Id=r.tPlant_Id  AND d.Batch_Date='2015-12-31' AND d.status_check='0' AND d.Batch_No=r.Batch_No GROUP BY d.Batch_No limit 1");
            rs1=ps1.executeQuery();

            ExecutorService executor = Executors.newFixedThreadPool(1);
            while(rs1.next()) {

                ps2=con.prepareStatement("SELECT nPhNo1 FROM ct_contractor_info WHERE tcontractor_id='"+rs1.getString("tcontractor_id")+"' AND SUBSTRING(service_type,1,1)='1'");
                rs2=ps2.executeQuery();

                while(rs2.next()){
                    //phone_no=rs2.getString("nPhNo1");

                    Runnable worker = new WorkerThreadRMC(rs1.getString("id"),rs1.getString("Batch_No"),rs1.getString("tcontractor_id"),rs1.getString("twork_id"),rs1.getString("Batch_Time"),rs1.getString("Production_Qty"),rs1.getString("Gate1_Actual"),rs1.getString("Gate2_Actual"),rs1.getString("Gate3_Actual"),rs1.getString("Gate4_Actual"),rs1.getString("Cement1_Actual"),rs1.getString("Water1_Actual"),rs1.getString("Adm1_Actual1"),rs1.getString("Adm2_Actual1"),rs1.getString("Truck_No"),rs1.getString("Recipe_Name"),phone_no);
                    executor.execute(worker);
                }
            }
            executor.shutdown();
            while (!executor.isTerminated()) {

            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(rs1!=null){
                rs1.close();}
                if(rs2!=null){
                rs2.close();}
                if(ps1!=null){
                ps1.close();}
                if(ps2!=null){
                ps2.close();}
                if(con!=null){
                con.close();}
            } catch (SQLException e) {

                e.printStackTrace();
            }
        }

        System.out.println("Finished all threads");

        new SimpleThreadPoolRMC();
    }

    private void processCommand() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
     }

     public static void main(String[] args) {

         new SimpleThreadPoolRMC();  
     }
}

请给我一些有价值的解决方案。

1 个答案:

答案 0 :(得分:0)

您的代码类似于

public class SimpleThreadPoolRMC {

    public SimpleThreadPoolRMC() {
        // sleeps 5s
        processCommand();
        // call service method
        Service();
    }

    public void Service() {
        // build a threadpool, and run it for a particular query 
        // ...

        // gratitious recursion!
        new SimpleThreadPoolRMC();
    }

    public static void main(String[] args) {
        new SimpleThreadPoolRMC();  
    }
}

因此,您的堆栈会不断增长,直到您遇到异常。请改用:

public class SimpleThreadPoolRMC {

    public SimpleThreadPoolRMC() {
       // if no initialization performed, leaving this empty is ok
    }

    // changed name to lowercase
    public void service() {
        // build a threadpool, and run it for a particular query 
        // ...
    }

    public static void main(String[] args) {
        SimpleThreadPoolRMC simple = new SimpleThreadPoolRMC();
        while (true) {
            // sleeps 5s
            simple.processCommand();
            simple.service();
        }
    }
}

新版本是等效的,但使用迭代而不是递归,并且您的堆栈不应再爆炸。