2014-10-16 235 views
0

所以基本上我有一个java应用程序,它越来越慢,越来越慢(即使我重置我的JVM)。也没有检测到内存泄漏。在将VM选项操作为(-Xmx1024m)后,GC正常工作。为什么我的Java应用程序(没有内存泄漏)越来越慢

无论如何,我想要做的是运行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) { } 
    } 
} 

这是堆转储:

Java2D Disposer" daemon prio=10 tid=10 WAITING 
at java.lang.Object.wait(Native Method) 
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142) 
    Local Variable: java.lang.ref.ReferenceQueue#72 
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158) 
at sun.java2d.Disposer.run(Disposer.java:148) 
    Local Variable: sun.java2d.Disposer#1 
at java.lang.Thread.run(Thread.java:745) 


"SwingWorker-pool-1-thread-1" daemon prio=5 tid=21 WAITING 
at java.lang.Object.wait(Native Method) 
at java.lang.Thread.join(Thread.java:1245) 
at java.lang.Thread.join(Thread.java:1319) 
at simulator.Main_panel$simulation1.doInBackground(Main_panel.java:896) 
at simulator.Main_panel$simulation1.doInBackground(Main_panel.java:876) 
at javax.swing.SwingWorker$1.call(SwingWorker.java:295) 
at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    Local Variable: javax.swing.SwingWorker$2#1 
    Local Variable: javax.swing.SwingWorker$1#1 
at javax.swing.SwingWorker.run(SwingWorker.java:334) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    Local Variable: java.util.concurrent.ThreadPoolExecutor#1 
    Local Variable: simulator.Main_panel$simulation1#1 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    Local Variable: java.util.concurrent.ThreadPoolExecutor$Worker#1 
at java.lang.Thread.run(Thread.java:745) 


"*** Profiler Agent Special Execution Thread 6" daemon prio=5 tid=26 WAITING 
at java.lang.Object.wait(Native Method) 
at java.lang.Object.wait(Object.java:502) 
at  org.netbeans.lib.profiler.server.ProfilerServer$SeparateCmdExecutionThread.run(ProfilerServer.java:289) 


"*** JFluid Monitor thread ***" daemon prio=10 tid=25 TIMED_WAITING 
at java.lang.Thread.sleep(Native Method) 
at org.netbeans.lib.profiler.server.Monitors$SurvGenAndThreadsMonitor.run(Monitors.java:186) 


"Signal Dispatcher" daemon prio=9 tid=4 RUNNABLE 


"TimerQueue" daemon prio=5 tid=20 TIMED_WAITING 
at sun.misc.Unsafe.park(Native Method) 
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) 
    Local Variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$Node#8 
    Local Variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#3 
at java.util.concurrent.DelayQueue.take(DelayQueue.java:223) 
    Local Variable: java.util.concurrent.locks.ReentrantLock#77 
    Local Variable: java.util.concurrent.DelayQueue#1 
at javax.swing.TimerQueue.run(TimerQueue.java:171) 
    Local Variable: javax.swing.TimerQueue#1 
at java.lang.Thread.run(Thread.java:745) 


"Attach Listener" daemon prio=5 tid=5 RUNNABLE 


"Reference Handler" daemon prio=10 tid=2 WAITING 
at java.lang.Object.wait(Native Method) 
at java.lang.Object.wait(Object.java:502) 
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157) 


"Thread-1" prio=5 tid=14 RUNNABLE 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.read(SocketInputStream.java:150) 
    Local Variable: java.net.SocketInputStream#1 
    Local Variable: java.io.FileDescriptor#8 
    Local Variable: byte[]#472 
at java.net.SocketInputStream.read(SocketInputStream.java:121) 
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114) 
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161) 
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189) 
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2549) 
    Local Variable: com.mysql.jdbc.util.ReadAheadInputStream#1 
    Local Variable: byte[]#464 
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002) 
    Local Variable: com.mysql.jdbc.Buffer#2 
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2991) 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3532) 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002) 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163) 
    Local Variable: com.mysql.jdbc.MysqlIO#1 
    Local Variable: java.lang.String#287058 
    Local Variable: com.mysql.jdbc.Buffer#1 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618) 
    Local Variable: java.lang.String#286257 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568) 
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1557) 
    Local Variable: com.mysql.jdbc.StatementImpl#2 
    Local Variable: com.mysql.jdbc.JDBC4Connection#1 
at org.apache.commons.dbcp2.DelegatingStatement.executeQuery(DelegatingStatement.java:207) 
    Local Variable: org.apache.commons.dbcp2.DelegatingStatement#3 
at org.apache.commons.dbcp2.DelegatingStatement.executeQuery(DelegatingStatement.java:207) 
    Local Variable: org.apache.commons.dbcp2.DelegatingStatement#4 
at simulator.Main_panel$2.run(Main_panel.java:1011) 
    Local Variable: java.lang.String#346303 
    Local Variable: java.lang.String#751527 


"AWT-Shutdown" prio=5 tid=11 WAITING 
at java.lang.Object.wait(Native Method) 
at java.lang.Object.wait(Object.java:502) 
at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:295) 
    Local Variable: sun.awt.AWTAutoShutdown#1 
at java.lang.Thread.run(Thread.java:745) 


"Finalizer" daemon prio=8 tid=3 WAITING 
at java.lang.Object.wait(Native Method) 
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142) 
    Local Variable: java.lang.ref.ReferenceQueue#82 
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158) 
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) 
    Local Variable: java.lang.System$2#1 


"AWT-Windows" daemon prio=6 tid=12 RUNNABLE 
at sun.awt.windows.WToolkit.eventLoop(Native Method) 
at sun.awt.windows.WToolkit.run(WToolkit.java:303) 
    Local Variable: sun.awt.windows.WToolkit#1 
at java.lang.Thread.run(Thread.java:745) 


"DestroyJavaVM" prio=5 tid=19 RUNNABLE 


"AWT-EventQueue-0" prio=6 tid=16 WAITING 
at sun.misc.Unsafe.park(Native Method) 
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
    Local Variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#2 
    Local Variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$Node#4 
at java.awt.EventQueue.getNextEvent(EventQueue.java:542) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:170) 
    Local Variable: java.awt.EventQueue#1 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) 
    Local Variable: java.awt.EventDispatchThread$HierarchyEventFilter#1 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) 
    Local Variable: java.awt.EventDispatchThread$1#1 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 


"*** Profiler Agent Communication Thread" daemon prio=10 tid=24 RUNNABLE 
at sun.management.HotSpotDiagnostic.dumpHeap0(Native Method) 
at sun.management.HotSpotDiagnostic.dumpHeap(HotSpotDiagnostic.java:50) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    Local Variable: sun.management.HotSpotDiagnostic#2 
    Local Variable: sun.reflect.NativeMethodAccessorImpl#10 
    Local Variable: java.lang.Object[]#262773 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:483) 
at org.netbeans.lib.profiler.server.system.HeapDump.takeHeapDump16(HeapDump.java:165) 
    Local Variable: java.lang.String#751526 
at org.netbeans.lib.profiler.server.system.HeapDump.takeHeapDump(HeapDump.java:92) 
at org.netbeans.lib.profiler.server.ProfilerServer.handleClientCommand(ProfilerServer.java:1657) 
at org.netbeans.lib.profiler.server.ProfilerServer.listenToClient(ProfilerServer.java:1733) 
    Local Variable: org.netbeans.lib.profiler.wireprotocol.TakeHeapDumpCommand#1 
at org.netbeans.lib.profiler.server.ProfilerServer.run(ProfilerServer.java:690) 
+0

stmt.setFetchSize(Integer.MIN_VALUE的)? – 2014-10-16 13:09:40

+0

@BrianAgnew实际上这就是MySQL(也可能是其他一些)为了获得“不预取所有”行为而要求你设置的内容。 – 2014-10-16 13:11:54

+0

@MarkoTopolnik非常有趣。感谢那 – 2014-10-16 13:12:42

回答

0

它是完整的资源泄漏,主要是因为将一个变量重用于另一个对象实例,因此不会关闭先前的实例。

  • 变量声明为接近其第一使用和使用的try-与资源

    String sql1 = "..." 
    try (PreparedStatement pst1 = con.prepareStatement(sql1)) { 
    
        for (int a = 0; a < 100; ++a) { 
         pst1.setInt(1, a); 
         try (ResultSet rs1 = pst1.executeQuery()) { 
          while (rs1.next()) { 
          } 
         } // Safe close of rs1 
        } 
    
    } // Safe close of pst1 
    
  • 要接收所生成的主键,则AUTO_INCR柱,JAVA设计了一个供应商独立的机构:

    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 

并让我指出两个最好的做法:

  • 的代码太长,像rs1/rs2/rs3这样的编号会将代码暴露给混淆。尝试引入功能。给有意义的名字。

  • 同样的防御性编码:不设置内列if语句:

          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); 
    
+0

是的,试用资源就是答案,非常感谢,尽管你忘记了在预先准备好的情况下请求“生成密钥”。 – Payam 2014-10-23 20:12:45

相关问题