summaryrefslogtreecommitdiff
path: root/runtime/java_vm_ext.cc
diff options
context:
space:
mode:
author Dimitry Ivanov <dimitry@google.com> 2016-05-03 15:05:41 -0700
committer Dimitry Ivanov <dimitry@google.com> 2016-05-04 15:25:43 -0700
commit2eb3ba9fcc120b74bdf9f61342347379223973f3 (patch)
tree29ff9ed54bea36a22b19e7e5c7abd19c9f4c2ff3 /runtime/java_vm_ext.cc
parent2f8d3a6d08436be37b8087d7c7bb34b2b8e10e0e (diff)
(dl)Close native libraries on unload
Dlclose native libraries when VM unloads a classloader. This change is made to avoid leakage of adress space and RSS for mapped but unreachable native libraries. Bug: http://b/28406866 Change-Id: Iccaa87210908872c2013506d8a310955c1e3d888 (cherry picked from commit 35f01195c4cf6e3c6fbb8b51f5a41b26132b4bdd)
Diffstat (limited to 'runtime/java_vm_ext.cc')
-rw-r--r--runtime/java_vm_ext.cc31
1 files changed, 17 insertions, 14 deletions
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index 35bb3c3301..eebcc689c9 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -74,6 +74,10 @@ class SharedLibrary {
if (self != nullptr) {
self->GetJniEnv()->DeleteWeakGlobalRef(class_loader_);
}
+
+ if (!needs_native_bridge_) {
+ android::CloseNativeLibrary(handle_);
+ }
}
jweak GetClassLoader() const {
@@ -271,8 +275,7 @@ class Libraries {
REQUIRES(!Locks::jni_libraries_lock_)
SHARED_REQUIRES(Locks::mutator_lock_) {
ScopedObjectAccessUnchecked soa(Thread::Current());
- typedef void (*JNI_OnUnloadFn)(JavaVM*, void*);
- std::vector<JNI_OnUnloadFn> unload_functions;
+ std::vector<SharedLibrary*> unload_libraries;
{
MutexLock mu(soa.Self(), *Locks::jni_libraries_lock_);
for (auto it = libraries_.begin(); it != libraries_.end(); ) {
@@ -283,15 +286,7 @@ class Libraries {
// the native libraries of the boot class loader.
if (class_loader != nullptr &&
soa.Self()->IsJWeakCleared(class_loader)) {
- void* const sym = library->FindSymbol("JNI_OnUnload", nullptr);
- if (sym == nullptr) {
- VLOG(jni) << "[No JNI_OnUnload found in \"" << library->GetPath() << "\"]";
- } else {
- VLOG(jni) << "[JNI_OnUnload found for \"" << library->GetPath() << "\"]";
- JNI_OnUnloadFn jni_on_unload = reinterpret_cast<JNI_OnUnloadFn>(sym);
- unload_functions.push_back(jni_on_unload);
- }
- delete library;
+ unload_libraries.push_back(library);
it = libraries_.erase(it);
} else {
++it;
@@ -299,9 +294,17 @@ class Libraries {
}
}
// Do this without holding the jni libraries lock to prevent possible deadlocks.
- for (JNI_OnUnloadFn fn : unload_functions) {
- VLOG(jni) << "Calling JNI_OnUnload";
- (*fn)(soa.Vm(), nullptr);
+ typedef void (*JNI_OnUnloadFn)(JavaVM*, void*);
+ for (auto library : unload_libraries) {
+ void* const sym = library->FindSymbol("JNI_OnUnload", nullptr);
+ if (sym == nullptr) {
+ VLOG(jni) << "[No JNI_OnUnload found in \"" << library->GetPath() << "\"]";
+ } else {
+ VLOG(jni) << "[JNI_OnUnload found for \"" << library->GetPath() << "\"]: Calling...";
+ JNI_OnUnloadFn jni_on_unload = reinterpret_cast<JNI_OnUnloadFn>(sym);
+ jni_on_unload(soa.Vm(), nullptr);
+ }
+ delete library;
}
}