[android] MapRendererRunnable - avoid weak reference table overflow

Apparently on some devices the weak reference table is limited (numbers around 52000). Even though we don't use that many weak references, when GC is not called for a while they can stack up and a crash will occur before the GC has had the time to clear the references. The C++ peer now holds on to a global ref (strong) which can be obtained to queue the java peer and then release automatically so that the GC can take over after the runnable has been executed.
This commit is contained in:
Ivo van Dongen
2017-11-08 15:28:03 +02:00
committed by Ivo van Dongen
parent 43f89d6b6a
commit c30161e4c8
3 changed files with 16 additions and 11 deletions

View File

@@ -41,15 +41,19 @@ ActorRef<Renderer> MapRenderer::actor() const {
}
void MapRenderer::schedule(std::weak_ptr<Mailbox> scheduled) {
// Create a runnable and schedule it on the gl thread
// Create a runnable
android::UniqueEnv _env = android::AttachEnv();
auto runnable = std::make_unique<MapRendererRunnable>(*_env, std::move(scheduled));
// Obtain ownership of the peer (gets transferred to the MapRenderer on the JVM for later GC)
auto peer = runnable->peer();
// Queue the event on the Java Peer
static auto queueEvent = javaClass.GetMethod<void(
jni::Object<MapRendererRunnable>)>(*_env, "queueEvent");
javaPeer->Call(*_env, queueEvent, runnable->getPeer());
javaPeer->Call(*_env, queueEvent, *peer);
// Release the object as it will be destroyed on GC of the Java Peer
// Release the c++ peer as it will be destroyed on GC of the Java Peer
runnable.release();
}