summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libart/src/main/java/dalvik/system/VMRuntime.java25
-rw-r--r--luni/src/main/java/java/lang/Runtime.java12
-rw-r--r--luni/src/main/java/java/lang/ref/FinalizerReference.java21
3 files changed, 47 insertions, 11 deletions
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index b885ed2..aa3f154 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -16,6 +16,7 @@
package dalvik.system;
+import java.lang.ref.FinalizerReference;
import java.util.HashMap;
import java.util.Map;
@@ -301,6 +302,30 @@ public final class VMRuntime {
*/
public native void registerNativeFree(int bytes);
+ /**
+ * Wait for objects to be finalized.
+ *
+ * If finalization takes longer than timeout, then the function returns before all objects are
+ * finalized.
+ *
+ * @param timeout
+ * timeout in nanoseconds of the maximum time to wait until all pending finalizers
+ * are run. If timeout is 0, then there is no timeout. Note that the timeout does
+ * not stop the finalization process, it merely stops the wait.
+ *
+ * @see #Runtime.runFinalization()
+ * @see #wait(long,int)
+ */
+ public static void runFinalization(long timeout) {
+ try {
+ FinalizerReference.finalizeAllEnqueued(timeout);
+ } catch (InterruptedException e) {
+ // Interrupt the current thread without actually throwing the InterruptionException
+ // for the caller.
+ Thread.currentThread().interrupt();
+ }
+ }
+
public native void requestConcurrentGC();
public native void concurrentGC();
public native void requestHeapTrim();
diff --git a/luni/src/main/java/java/lang/Runtime.java b/luni/src/main/java/java/lang/Runtime.java
index 3ddacf7..ad549f2 100644
--- a/luni/src/main/java/java/lang/Runtime.java
+++ b/luni/src/main/java/java/lang/Runtime.java
@@ -34,6 +34,7 @@ package java.lang;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.VMDebug;
+import dalvik.system.VMRuntime;
import dalvik.system.VMStack;
import java.io.File;
import java.io.IOException;
@@ -438,20 +439,17 @@ public class Runtime {
String ldLibraryPath, String dexPath);
/**
- * Provides a hint to the VM that it would be useful to attempt
+ * Provides a hint to the runtime that it would be useful to attempt
* to perform any outstanding object finalization.
*/
public void runFinalization() {
- try {
- FinalizerReference.finalizeAllEnqueued();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
+ // 0 for no timeout.
+ VMRuntime.runFinalization(0);
}
/**
* Sets the flag that indicates whether all objects are finalized when the
- * VM is about to exit. Note that all finalization which occurs
+ * runtime is about to exit. Note that all finalization which occurs
* when the system is exiting is performed after all running threads have
* been terminated.
*
diff --git a/luni/src/main/java/java/lang/ref/FinalizerReference.java b/luni/src/main/java/java/lang/ref/FinalizerReference.java
index 5416a80..02cfa01 100644
--- a/luni/src/main/java/java/lang/ref/FinalizerReference.java
+++ b/luni/src/main/java/java/lang/ref/FinalizerReference.java
@@ -82,7 +82,7 @@ public final class FinalizerReference<T> extends Reference<T> {
/**
* Waits for all currently-enqueued references to be finalized.
*/
- public static void finalizeAllEnqueued() throws InterruptedException {
+ public static void finalizeAllEnqueued(long timeout) throws InterruptedException {
// Alloate a new sentinel, this creates a FinalizerReference.
Sentinel sentinel;
// Keep looping until we safely enqueue our sentinel FinalizerReference.
@@ -91,7 +91,7 @@ public final class FinalizerReference<T> extends Reference<T> {
do {
sentinel = new Sentinel();
} while (!enqueueSentinelReference(sentinel));
- sentinel.awaitFinalization();
+ sentinel.awaitFinalization(timeout);
}
private static boolean enqueueSentinelReference(Sentinel sentinel) {
@@ -144,9 +144,22 @@ public final class FinalizerReference<T> extends Reference<T> {
notifyAll();
}
- synchronized void awaitFinalization() throws InterruptedException {
+ synchronized void awaitFinalization(long timeout) throws InterruptedException {
+ final long startTime = System.nanoTime();
+ final long endTime = startTime + timeout;
while (!finalized) {
- wait();
+ // 0 signifies no timeout.
+ if (timeout != 0) {
+ final long currentTime = System.nanoTime();
+ if (currentTime >= endTime) {
+ break;
+ } else {
+ final long deltaTime = endTime - currentTime;
+ wait(deltaTime / 1000000, (int)(deltaTime % 1000000));
+ }
+ } else {
+ wait();
+ }
}
}
}