为什么我的Java应用程序(没有内存泄漏)会随着时间的推移变得越来越慢

为什么我的Java应用程序(没有内存泄漏)会随着时间的推移变得越来越慢,java,performance,memory-leaks,garbage-collection,Java,Performance,Memory Leaks,Garbage Collection,因此,基本上我有一个java应用程序,即使我重置JVM,它也会随着时间的推移变得越来越慢。也没有检测到内存泄漏。在我将VM选项设置为-Xmx1024m后,GC工作正常 不管怎样,我试着做的是运行一个for循环,里面有一些代码超过40000次,但是速度越来越慢 循环是这样的,我必须删除针对版权问题的SQL查询: for (int ab = m;ab<=(duration);ab+=600){ jLabel_current.setText(String.valueOf(ab/600))

因此,基本上我有一个java应用程序,即使我重置JVM,它也会随着时间的推移变得越来越慢。也没有检测到内存泄漏。在我将VM选项设置为-Xmx1024m后,GC工作正常

不管怎样,我试着做的是运行一个for循环,里面有一些代码超过40000次,但是速度越来越慢

循环是这样的,我必须删除针对版权问题的SQL查询:

for (int ab = m;ab<=(duration);ab+=600){
    jLabel_current.setText(String.valueOf(ab/600));
    System.out.println(String.valueOf(ab/600));
    System.out.println(String.valueOf(loop));

    try{
        con = datasource.getConnection();   
        for (int i=1;i<=4;i++){

            String sql=" Some query ";
            stmt = con.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                    java.sql.ResultSet.CONCUR_READ_ONLY);
            stmt.setFetchSize(Integer.MIN_VALUE);
            System.out.println(sql);
            stmt = con.createStatement();
            rs=stmt.executeQuery(sql);

            while(rs.next()){
                int a =rs.getInt("columnName");

                sql="Some query";          
                pst1=con.prepareStatement(sql);
                rs1=pst1.executeQuery();
                if(rs1.next()){                                      
                    x=rs1.getInt("columnName");
                    for(int b=0;b<x;b++){
                        if (loop!=max){
                            int task_id=parseWithDefault((jTable_task_main.getModel().getValueAt(loop, 1).toString()),0);
                            int jobb_id=parseWithDefault((jTable_task_main.getModel().getValueAt(loop, 4).toString()),0);
                            int idk=Integer.parseInt(String.valueOf(curTimeinner));
                            sql="insert into ";
                            pst2=con.prepareStatement(sql);
                            pst2.setInt(1, a);
                            pst2.setInt(2, rs1.getInt("columnName"));
                            pst2.setInt(3, rs1.getInt("columnName"));
                            pst2.setInt(4, rs1.getInt("columnName"));
                            pst2.setInt(5, rs1.getInt("columnName"));
                            pst2.setDouble(6, rs1.getDouble("columnName"));
                            pst2.setDouble(7, rs1.getDouble("columnName"));
                            pst2.setInt(8, rs1.getInt("columnName"));
                            pst2.setInt(9, rs1.getInt("columnName"));
                            pst2.setInt(10,n);
                            pst2.setInt(11,m); 
                            pst2.setInt(12, g);

                            if(rs1.getLong("columnName")<=curTime){
                                currDuration=endTask-curTimeinner;
                                pst2.setLong(13, endTask);
                                pst2.setLong(14,currDuration );

                                if(rs.getLong("columnName")>endTask){
                                    currTaskOut="successful";
                                    pst2.setString(15, currTaskOut);
                                    pst2.setInt(16, loop);
                                }else{
                                    currTaskOut="unsuccessful";
                                    pst2.setString(15, currTaskOut);
                                    pst2.setInt(16, loop);
                                }

                            }else {
                                endTask2=rs1.getLong("columnName")+120;
                                pst2.setLong(13, endTask2);
                                pst2.setLong(14, currDuration);

                                if(rs.getLong("columnName")>endTask2){
                                    currTaskOut="successful";
                                    pst2.setString(15, currTaskOut);
                                    pst2.setInt(16, loop);
                                }else{
                                    currTaskOut="unsuccessful";
                                    pst2.setString(15, currTaskOut);
                                    pst2.setInt(16, loop);
                                }                                            
                            }

                            pst2.execute();

                            loop+=1;

                            if(loop%4==0){
                                curTimeinner+=600;

                                String outcome=null;
                                String out1 = null;
                                String out2 = null;
                                String out3 = null;
                                String out4 = null;
                                ResultSet rs3=null;
                                for (int bv = 1; bv <= 4; bv++) {
                                    outcome = "unsuccessful";
                                    String sql1 = "select statment";
                                    pst1 = con.prepareStatement(sql);
                                    rs3 = pst1.executeQuery(sql1);
                                    while (rs3.next()) {
                                        if ("successful".equals(rs3.getString("task_outcome"))) {
                                            outcome = "successful";
                                        }
                                    }
                                    if (bv == 1) {
                                        out1 = outcome;
                                    } else if (bv == 2) {
                                        out2 = outcome;
                                    } else if (bv == 3) {
                                        out3 = outcome;
                                    } else {
                                        out4 = outcome;

                                        sql = "SELECT AUTO_INCREMENT";
                                        pst1 = con.prepareStatement(sql);
                                        rs3 = pst1.executeQuery(sql);
                                        if (rs3.next()) {
                                            res_id = rs3.getInt("AUTO_INCREMENT");
                                        }

                                        if ("successful".equals(out1) && "successful".equals(out2) && "successful".equals(out3) && "successful".equals(out4)) {
                                            sql = "update statment";
                                            pst1 = con.prepareStatement(sql);
                                            pst1.execute();
                                        } else {
                                            sql = "update statment";
                                            pst1 = con.prepareStatement(sql);
                                            pst1.execute();                                                                          
                                        }
                                    }
                                }
                            }
                        }
                    }
                    sql="update statment";
                    pst=con.prepareStatement(sql);
                    pst.execute(); 
                }
            }
        }
        curTime += 600;
        endTask += 600;
        ab+=600;
        max+=4;

        String sql="update statment";
        pst=con.prepareStatement(sql);
        pst.execute(); 
        ab-=600;
    }                                   

    catch (SQLException e ) {
        JOptionPane.showMessageDialog(null, e);
    } finally {
        try { if (rs != null) rs.close(); } catch(Exception e) { }
        try { if (stmt != null) stmt.close(); } catch(Exception e) { }
        try { if (con != null) con.close(); } catch(Exception e) { }
        try { if (pst != null) pst.close(); } catch(Exception e) { }
        try { if (rs1 != null) rs1.close(); } catch(Exception e) { }
        try { if (pst1 != null) pst1.close(); } catch(Exception e) { }
        try { if (rs2 != null) rs2.close(); } catch(Exception e) { }
        try { if (pst2 != null) pst2.close(); } catch(Exception e) { }
    }  
}

它充满了资源泄漏,主要是因为为另一个对象实例重用了一个变量,因此没有关闭先前的实例

将变量声明为接近其第一次使用,并使用try with资源:

这就解决了并发性问题,当两个插入同时发生时,新生成的密钥被获取:

1. A inserts
2. B inserts
3. B asks generated key
4. A asks generated key
请允许我指出两个最佳做法:

代码太长,像rs1/rs2/rs3这样的编号会使代码混淆。尝试介绍函数。给出有意义的全名

相同的防御性编码:不要在if语句中设置第i列:

                            int endTask = 0;
                            int currDuration = 0;
                            String currTaskOut = "";
                            if (rs1.getLong("columnName") <= curTime) {
                                //if (rs.getLong("columnName") > ...) {
                                endTask = ...;
                                currDuration = ...;
                            } else {
                                //...
                            }
                            pst2.setLong(13, endTask);
                            pst2.setLong(14, currDuration);
                            pst2.setString(15, currTaskOut);
                            pst2.setInt(16, loop);

stmt.setFetchSizeInteger.MIN_VALUE?@BrianAgnew实际上这就是MySQL可能还有其他人要求您设置的,以便获得“不要预取所有内容”行为。@MarkoTopolnik非常有趣。谢谢你的建议,来点礼貌的格式化怎么样?你让我们在两个维度上滚动,同时试图理解它。@Brian Agnew Yep“尝试使用资源”就是答案。非常感谢,尽管您忘记在PreparedStation中请求生成的密钥。
String sql1 = "INSERT INTO table(col2, col3) VALUES(?, ?)";
try (PreparedStatement pst1 = con.prepareStatement(sql1, Statement.RETURN_GENERATED_KEYS))) {
     int updateCount = pst1.executeUpdate();
     if (updateCount != 0) { // Records inserted?
         int res_id = 0; // Key
         try (ResultSet generatedKeysRS = pst1.getGeneratedKeys()) {
              if (generatedKeysRS.next()) {
                  res_id = generatedKeysRS.getInt(1);
              }
         }
     }
 }
1. A inserts
2. B inserts
3. B asks generated key
4. A asks generated key
                            int endTask = 0;
                            int currDuration = 0;
                            String currTaskOut = "";
                            if (rs1.getLong("columnName") <= curTime) {
                                //if (rs.getLong("columnName") > ...) {
                                endTask = ...;
                                currDuration = ...;
                            } else {
                                //...
                            }
                            pst2.setLong(13, endTask);
                            pst2.setLong(14, currDuration);
                            pst2.setString(15, currTaskOut);
                            pst2.setInt(16, loop);