Move heap trimming daemon and GC deamon into a single daemon
Bug: 18739541
Change-Id: Icf309cd8981372f24caa7c8b98a2e0591b1d90ea
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 58094d8..b054fb3 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -295,10 +295,13 @@
*/
public native void registerNativeFree(int bytes);
- public native void trimHeap();
- public native void concurrentGC();
public native void requestConcurrentGC();
- public native void waitForConcurrentGCRequest();
+ public native void concurrentGC();
+ public native void requestHeapTrim();
+ public native void trimHeap();
+ public native void startHeapTaskProcessor();
+ public native void stopHeapTaskProcessor();
+ public native void runHeapTasks();
/**
* Let the heap know of the new process state. This can change allocation and garbage collection
diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
index d3f62c2..76f4ea9 100644
--- a/libart/src/main/java/java/lang/Daemons.java
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -40,16 +40,14 @@
ReferenceQueueDaemon.INSTANCE.start();
FinalizerDaemon.INSTANCE.start();
FinalizerWatchdogDaemon.INSTANCE.start();
- HeapTrimmerDaemon.INSTANCE.start();
- GCDaemon.INSTANCE.start();
+ HeapTaskDaemon.INSTANCE.start();
}
public static void stop() {
+ HeapTaskDaemon.INSTANCE.stop();
ReferenceQueueDaemon.INSTANCE.stop();
FinalizerDaemon.INSTANCE.stop();
FinalizerWatchdogDaemon.INSTANCE.stop();
- HeapTrimmerDaemon.INSTANCE.stop();
- GCDaemon.INSTANCE.stop();
}
/**
@@ -292,45 +290,38 @@
}
}
- // Invoked by the GC to request that the HeapTrimmerDaemon thread attempt to trim the heap.
+ // Adds a heap trim task ot the heap event processor, not called from java. Left for
+ // compatibility purposes due to reflection.
public static void requestHeapTrim() {
- synchronized (HeapTrimmerDaemon.INSTANCE) {
- HeapTrimmerDaemon.INSTANCE.notify();
- }
+ VMRuntime.getRuntime().requestHeapTrim();
}
- private static class HeapTrimmerDaemon extends Daemon {
- private static final HeapTrimmerDaemon INSTANCE = new HeapTrimmerDaemon();
-
- @Override public void run() {
- while (isRunning()) {
- try {
- synchronized (this) {
- wait();
- }
- VMRuntime.getRuntime().trimHeap();
- } catch (InterruptedException ignored) {
- }
- }
- }
+ // Adds a concurrent GC request task ot the heap event processor, not called from java. Left
+ // for compatibility purposes due to reflection.
+ public static void requestGC() {
+ VMRuntime.getRuntime().requestConcurrentGC();
}
- private static class GCDaemon extends Daemon {
- private static final GCDaemon INSTANCE = new GCDaemon();
+ private static class HeapTaskDaemon extends Daemon {
+ private static final HeapTaskDaemon INSTANCE = new HeapTaskDaemon();
// Overrides the Daemon.interupt method which is called from Daemons.stop.
- public void interrupt(Thread thread) {
- // Notifies the daemon thread.
- VMRuntime.getRuntime().requestConcurrentGC();
+ public synchronized void interrupt(Thread thread) {
+ VMRuntime.getRuntime().stopHeapTaskProcessor();
}
@Override public void run() {
- while (isRunning()) {
- VMRuntime.getRuntime().waitForConcurrentGCRequest();
+ synchronized (this) {
if (isRunning()) {
- VMRuntime.getRuntime().concurrentGC();
+ // Needs to be synchronized or else we there is a race condition where we start
+ // the thread, call stopHeapTaskProcessor before we start the heap task
+ // processor, resulting in a deadlock since startHeapTaskProcessor restarts it
+ // while the other thread is waiting in Daemons.stop().
+ VMRuntime.getRuntime().startHeapTaskProcessor();
}
}
+ // This runs tasks until we are stopped and there is no more pending task.
+ VMRuntime.getRuntime().runHeapTasks();
}
}
}