diff options
-rw-r--r-- | libart/src/main/java/dalvik/system/VMRuntime.java | 25 | ||||
-rw-r--r-- | luni/src/main/java/java/lang/Runtime.java | 12 | ||||
-rw-r--r-- | luni/src/main/java/java/lang/ref/FinalizerReference.java | 21 |
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(); + } } } } |