diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-12-09 12:51:40 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-12-09 13:17:03 +0100 |
commit | 6ddde10b4006ece33bc358a391a13e108a35f6fa (patch) | |
tree | 2a1b66691b588c2cb931934133fc911b052ae61b /cppuhelper | |
parent | 4c66ce8ec8f67d3bc2db5c79de68f4bda26d2e60 (diff) |
rhbz#1036877: Join Java AsynchronousFinalizer thread well before exit
AsynchronousFinalizer was originally added as
870a4401c05beec3d31c1f6055a64591edd0a9d9 "INTEGRATION: CWS mtg1: #i57753# Avoid
long-running finalize methods" referring to
<https://issues.apache.org/ooo/show_bug.cgi?id=57753> " Fix JNI-UNO bridge so
that the JVM doesn't run out of memory when a destructor locks the SolarMutex."
It is unclear to me how relevant "If JVMs are getting more mature and should no
longer have problems with long-running finalize methods, this class could be
removed again" really is in practice. After all, advice on hotspot-gc-devel is
to avoid finalize() if possible
(<http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2014-June/010215.html>
"Re: History of finalizer execution and gc progress?"). So stick with this
approach of home-grown draining for now (where a home-grown approach using
PhantomReferencens would need a dedicated draining thread, too, so would not
have much benefit over the existing code in practice).
Timely termination of AsynchronousFinalizer threads is achieved by using a
dedicated thread per bridge and joining it in the remote bridge's dispose()
resp. the JNI environment's new java_env_dispose.
Change-Id: Idcef2dbf361a1de22f60db73828f59e85711aea7
Diffstat (limited to 'cppuhelper')
-rw-r--r-- | cppuhelper/source/component_context.cxx | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/cppuhelper/source/component_context.cxx b/cppuhelper/source/component_context.cxx index 16642e9133fb..53b5eb000468 100644 --- a/cppuhelper/source/component_context.cxx +++ b/cppuhelper/source/component_context.cxx @@ -731,6 +731,22 @@ void ComponentContext::disposing() for ( ; iPos != iEnd; ++iPos ) delete iPos->second; m_map.clear(); + + // Hack to terminate any JNI bridge's AsynchronousFinalizer thread (as JNI + // proxies get finalized with arbitrary delay, so the bridge typically does + // not dispose itself early enough before the process exits): + uno_Environment ** envs; + sal_Int32 envCount; + uno_getRegisteredEnvironments( + &envs, &envCount, &rtl_allocateMemory, OUString("java").pData); + assert(envCount >= 0); + assert(envCount == 0 || envs != nullptr); + for (sal_Int32 i = 0; i != envCount; ++i) { + assert(envs[i] != nullptr); + assert(envs[i]->dispose != nullptr); + (*envs[i]->dispose)(envs[i]); + } + rtl_freeMemory(envs); } ComponentContext::ComponentContext( |