You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2013/06/12 09:35:40 UTC

svn commit: r1492094 - in /db/derby/code/trunk/java: engine/org/apache/derby/ engine/org/apache/derby/iapi/services/timer/ engine/org/apache/derby/impl/services/timer/ engine/org/apache/derby/impl/sql/conn/ engine/org/apache/derby/jdbc/ testing/org/apa...

Author: kahatlen
Date: Wed Jun 12 07:35:40 2013
New Revision: 1492094

URL: http://svn.apache.org/r1492094
Log:
DERBY-6114: OOME in XAMemTest.testDerby4137_TransactionTimeoutSpecifiedNotExceeded

Periodically run purge() on the cancellation timer to reclaim the
space occupied by cancelled tasks.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/Java5SingletonTimerFactory.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java
    db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memory/_Suite.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java?rev=1492094&r1=1492093&r2=1492094&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java Wed Jun 12 07:35:40 2013
@@ -21,7 +21,7 @@
 
 package org.apache.derby.iapi.services.timer;
 
-import java.util.Timer;
+import java.util.TimerTask;
 
 /**
  * This class provides access to Timer objects for various purposes.
@@ -30,10 +30,17 @@ import java.util.Timer;
 public interface TimerFactory
 {
     /**
-     * Returns a Timer object that can be used for adding TimerTasks
-     * that cancel executing statements.
+     * Schedule a task.
      *
-     * @return a Timer object for cancelling statements.
+     * @param task the task to schedule
+     * @param delay how many milliseconds to wait before executing the task
      */
-    public Timer getCancellationTimer();
+    void schedule(TimerTask task, long delay);
+
+    /**
+     * Cancel a task.
+     *
+     * @param task the task to cancel
+     */
+    void cancel(TimerTask task);
 }

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/Java5SingletonTimerFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/Java5SingletonTimerFactory.java?rev=1492094&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/Java5SingletonTimerFactory.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/Java5SingletonTimerFactory.java Wed Jun 12 07:35:40 2013
@@ -0,0 +1,54 @@
+/*
+
+   Derby - Class org.apache.derby.impl.services.timer.Java5SingletonTimerFactory
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.impl.services.timer;
+
+import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Extension of {@code SingletonTimerFactory} that takes advantage of the
+ * new {@code Timer.purge()} method in Java 5.
+ */
+public class Java5SingletonTimerFactory extends SingletonTimerFactory {
+    /**
+     * The number of times {@link #cancel(TimerTask)} has been called.
+     * Used for determining whether it's time to purge cancelled tasks from
+     * the timer.
+     */
+    private final AtomicInteger cancelCount = new AtomicInteger();
+
+    @Override public void cancel(TimerTask task) {
+        super.cancel(task);
+
+        // DERBY-6114: Cancelled tasks stay in the timer's queue until they
+        // are scheduled to run, unless we call the purge() method. This
+        // prevents garbage collection of the tasks. Even though the tasks
+        // are small objects, there could be many of them, especially when
+        // both the transaction throughput and tasks' delays are high, it
+        // could lead to OutOfMemoryErrors. Since purge() could be a heavy
+        // operation if the queue is big, we don't call it every time a task
+        // is cancelled.
+        if (cancelCount.incrementAndGet() % 1000 == 0) {
+            getCancellationTimer().purge();
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/Java5SingletonTimerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java?rev=1492094&r1=1492093&r2=1492094&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java Wed Jun 12 07:35:40 2013
@@ -29,6 +29,7 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Timer;
 import java.util.Properties;
+import java.util.TimerTask;
 
 
 /**
@@ -119,17 +120,27 @@ public class SingletonTimerFactory
      * Returns a Timer object that can be used for adding TimerTasks
      * that cancel executing statements.
      *
-     * Implements the TimerFactory interface.
-     *
      * @return a Timer object for cancelling statements.
-     *
-     * @see TimerFactory
      */
-    public Timer getCancellationTimer()
+    Timer getCancellationTimer()
     {
         return singletonTimer;
     }
 
+    // TimerFactory interface methods
+
+    /** {@inheritDoc} */
+    public void schedule(TimerTask task, long delay) {
+        singletonTimer.schedule(task, delay);
+    }
+
+    /** {@inheritDoc} */
+    public void cancel(TimerTask task) {
+        task.cancel();
+    }
+
+    // ModuleControl interface methods
+
     /**
      * Currently does nothing, singleton Timer instance is initialized
      * in the constructor.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java?rev=1492094&r1=1492093&r2=1492094&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java Wed Jun 12 07:35:40 2013
@@ -50,7 +50,6 @@ import org.apache.derby.iapi.error.Excep
 import org.apache.derby.iapi.reference.SQLState;
 import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.Timer;
 import java.util.TimerTask;
 
 /**
@@ -184,10 +183,14 @@ final class GenericStatementContext 
             synchronized (this) {
                 statementContext = null;
             }
-            cancel();
+            getTimerFactory().cancel(this);
         }
     }
 
+    private static TimerFactory getTimerFactory() {
+        return Monitor.getMonitor().getTimerFactory();
+    }
+
 	// StatementContext Interface
 
 	public void setInUse
@@ -209,10 +212,8 @@ final class GenericStatementContext 
 		this.pvs = pvs;
 		rollbackParentContext = false;
         if (timeoutMillis > 0) {
-            TimerFactory factory = Monitor.getMonitor().getTimerFactory();
-            Timer timer = factory.getCancellationTimer();
             cancelTask = new CancelQueryTask(this);
-            timer.schedule(cancelTask, timeoutMillis);
+            getTimerFactory().schedule(cancelTask, timeoutMillis);
         }
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java?rev=1492094&r1=1492093&r2=1492094&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java Wed Jun 12 07:35:40 2013
@@ -23,7 +23,6 @@ package org.apache.derby.jdbc;
 
 
 import java.sql.SQLException;
-import java.util.Timer;
 import java.util.TimerTask;
 import org.apache.derby.iapi.services.monitor.Monitor;
 import org.apache.derby.iapi.services.timer.TimerFactory;
@@ -120,7 +119,9 @@ final class XATransactionState extends C
         }
     }
 
-
+    private static TimerFactory getTimerFactory() {
+        return Monitor.getMonitor().getTimerFactory();
+    }
 
 	XATransactionState(ContextManager cm, EmbedConnection conn, 
                 EmbedXAResource resource, XAXactId xid) {
@@ -317,7 +318,7 @@ final class XATransactionState extends C
 	}
 
    /**
-    * Schedule a timeout task wich will rollback the global transaction
+    * Schedule a timeout task which will rollback the global transaction
     * after the specified time will elapse.
     *
     * @param timeoutMillis The number of milliseconds to be elapsed before
@@ -329,10 +330,8 @@ final class XATransactionState extends C
         // schedule a time out task if the timeout was specified
         if (timeoutMillis > 0) {
             // take care of the transaction timeout
-            TimerFactory timerFactory = Monitor.getMonitor().getTimerFactory();
-            Timer timer = timerFactory.getCancellationTimer();
             timeoutTask = new CancelXATransactionTask(this);
-            timer.schedule(timeoutTask, timeoutMillis);
+            getTimerFactory().schedule(timeoutTask, timeoutMillis);
         } else {
             timeoutTask = null;
         }
@@ -377,7 +376,7 @@ final class XATransactionState extends C
       */
     private void xa_finalize() {
         if (timeoutTask != null) {
-            timeoutTask.cancel();
+            getTimerFactory().cancel(timeoutTask);
             timeoutTask = null;
         }
         performTimeoutRollback = false;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/modules.properties?rev=1492094&r1=1492093&r2=1492094&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/modules.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/modules.properties Wed Jun 12 07:35:40 2013
@@ -129,8 +129,13 @@
 derby.module.uuidJ1=org.apache.derby.impl.services.uuid.BasicUUIDFactory
 cloudscape.config.uuidJ1=all
 
-derby.module.timer=org.apache.derby.impl.services.timer.SingletonTimerFactory
-cloudscape.config.timer=all
+derby.module.timerJ1=org.apache.derby.impl.services.timer.SingletonTimerFactory
+cloudscape.config.timerJ1=all
+
+# Use a different TimerFactory on Java 5 to take advantage of Timer.purge().
+derby.module.timerJ6=org.apache.derby.impl.services.timer.Java5SingletonTimerFactory
+derby.env.jdk.timerJ6=6
+cloudscape.config.timerJ6=all
 
 # ConcurrentCache requires JDK 1.5 (constant 6)
 derby.module.cacheManagerJ6=org.apache.derby.impl.services.cache.ConcurrentCacheFactory

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memory/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memory/_Suite.java?rev=1492094&r1=1492093&r2=1492094&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memory/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memory/_Suite.java Wed Jun 12 07:35:40 2013
@@ -43,8 +43,6 @@ public class _Suite extends BaseJDBCTest
         suite.addTest(Derby3009Test.suite());
         suite.addTest(Derby5730Test.suite());
         suite.addTest(MemoryLeakFixesTest.suite());
-
-        // DERBY-5394: Let this test run as the last test - it eats up memory.
         suite.addTest(XAMemTest.suite());
         return suite;
     }