Repository: hive
Updated Branches:
  refs/heads/master ae27806e4 -> b6d9dfe29


HIVE-16305: Additional Datanucleus ClassLoaderResolverImpl leaks causing HS2 
OOM (Daniel Dai, reviewed by Thejas Nair)


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/b6d9dfe2
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/b6d9dfe2
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/b6d9dfe2

Branch: refs/heads/master
Commit: b6d9dfe29151632b8b22585c5c4ef9fe663d9ef4
Parents: ae27806
Author: Daniel Dai <[email protected]>
Authored: Tue Mar 28 15:28:46 2017 -0700
Committer: Daniel Dai <[email protected]>
Committed: Tue Mar 28 15:28:46 2017 -0700

----------------------------------------------------------------------
 .../hadoop/hive/metastore/ObjectStore.java      | 70 +++++++++++++++++---
 1 file changed, 59 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/b6d9dfe2/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java
----------------------------------------------------------------------
diff --git 
a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java 
b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java
index c39c725..a63519a 100644
--- a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java
+++ b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java
@@ -158,8 +158,11 @@ import org.datanucleus.AbstractNucleusContext;
 import org.datanucleus.ClassLoaderResolver;
 import org.datanucleus.ClassLoaderResolverImpl;
 import org.datanucleus.NucleusContext;
+import org.datanucleus.api.jdo.JDOPersistenceManager;
 import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
 import org.datanucleus.store.rdbms.exceptions.MissingTableException;
+import org.datanucleus.store.scostore.Store;
+import org.datanucleus.util.WeakValueMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -8448,22 +8451,55 @@ public class ObjectStore implements RawStore, 
Configurable {
     JDOPersistenceManagerFactory jdoPmf = (JDOPersistenceManagerFactory) pmf;
     NucleusContext nc = jdoPmf.getNucleusContext();
     try {
+      Field pmCache = pmf.getClass().getDeclaredField("pmCache");
+      pmCache.setAccessible(true);
+      Set<JDOPersistenceManager> pmSet = 
(Set<JDOPersistenceManager>)pmCache.get(pmf);
+      for (JDOPersistenceManager pm : pmSet) {
+        org.datanucleus.ExecutionContext ec = 
(org.datanucleus.ExecutionContext)pm.getExecutionContext();
+        if (ec instanceof org.datanucleus.ExecutionContextThreadedImpl) {
+          ClassLoaderResolver clr = 
((org.datanucleus.ExecutionContextThreadedImpl)ec).getClassLoaderResolver();
+          clearClr(clr);
+        }
+      }
+      org.datanucleus.plugin.PluginManager pluginManager = 
jdoPmf.getNucleusContext().getPluginManager();
+      Field registryField = 
pluginManager.getClass().getDeclaredField("registry");
+      registryField.setAccessible(true);
+      org.datanucleus.plugin.PluginRegistry registry = 
(org.datanucleus.plugin.PluginRegistry)registryField.get(pluginManager);
+      if (registry instanceof org.datanucleus.plugin.NonManagedPluginRegistry) 
{
+        org.datanucleus.plugin.NonManagedPluginRegistry nRegistry = 
(org.datanucleus.plugin.NonManagedPluginRegistry)registry;
+        Field clrField = nRegistry.getClass().getDeclaredField("clr");
+        clrField.setAccessible(true);
+        ClassLoaderResolver clr = (ClassLoaderResolver)clrField.get(nRegistry);
+        clearClr(clr);
+      }
+      if (nc instanceof org.datanucleus.PersistenceNucleusContextImpl) {
+        org.datanucleus.PersistenceNucleusContextImpl pnc = 
(org.datanucleus.PersistenceNucleusContextImpl)nc;
+        org.datanucleus.store.types.TypeManagerImpl tm = 
(org.datanucleus.store.types.TypeManagerImpl)pnc.getTypeManager();
+        Field clrField = tm.getClass().getDeclaredField("clr");
+        clrField.setAccessible(true);
+        ClassLoaderResolver clr = (ClassLoaderResolver)clrField.get(tm);
+        clearClr(clr);
+        Field storeMgrField = pnc.getClass().getDeclaredField("storeMgr");
+        storeMgrField.setAccessible(true);
+        org.datanucleus.store.rdbms.RDBMSStoreManager storeMgr = 
(org.datanucleus.store.rdbms.RDBMSStoreManager)storeMgrField.get(pnc);
+        Field backingStoreField = 
storeMgr.getClass().getDeclaredField("backingStoreByMemberName");
+        backingStoreField.setAccessible(true);
+        Map<String, Store> backingStoreByMemberName = (Map<String, 
Store>)backingStoreField.get(storeMgr);
+        for (Store store : backingStoreByMemberName.values()) {
+          org.datanucleus.store.rdbms.scostore.BaseContainerStore baseStore = 
(org.datanucleus.store.rdbms.scostore.BaseContainerStore)store;
+          clrField = 
org.datanucleus.store.rdbms.scostore.BaseContainerStore.class.getDeclaredField("clr");
+          clrField.setAccessible(true);
+          clr = (ClassLoaderResolver)clrField.get(baseStore);
+          clearClr(clr);
+        }
+      }
       Field classLoaderResolverMap = 
AbstractNucleusContext.class.getDeclaredField(
           "classLoaderResolverMap");
       classLoaderResolverMap.setAccessible(true);
       Map<String,ClassLoaderResolver> loaderMap =
           (Map<String, ClassLoaderResolver>) classLoaderResolverMap.get(nc);
       for (ClassLoaderResolver clr : loaderMap.values()){
-        if (clr != null){
-          if (clr instanceof ClassLoaderResolverImpl){
-            ClassLoaderResolverImpl clri = (ClassLoaderResolverImpl) clr;
-            long resourcesCleared = clearFieldMap(clri,"resources");
-            long loadedClassesCleared = clearFieldMap(clri,"loadedClasses");
-            long unloadedClassesCleared = clearFieldMap(clri, 
"unloadedClasses");
-            LOG.debug("Cleared ClassLoaderResolverImpl: " +
-                resourcesCleared + "," + loadedClassesCleared + "," + 
unloadedClassesCleared);
-          }
-        }
+        clearClr(clr);
       }
       classLoaderResolverMap.set(nc, new HashMap<String, 
ClassLoaderResolver>());
       LOG.debug("Removed cached classloaders from DataNucleus NucleusContext");
@@ -8472,13 +8508,25 @@ public class ObjectStore implements RawStore, 
Configurable {
     }
   }
 
+  private static void clearClr(ClassLoaderResolver clr) throws Exception {
+    if (clr != null){
+      if (clr instanceof ClassLoaderResolverImpl){
+        ClassLoaderResolverImpl clri = (ClassLoaderResolverImpl) clr;
+        long resourcesCleared = clearFieldMap(clri,"resources");
+        long loadedClassesCleared = clearFieldMap(clri,"loadedClasses");
+        long unloadedClassesCleared = clearFieldMap(clri, "unloadedClasses");
+        LOG.debug("Cleared ClassLoaderResolverImpl: " +
+            resourcesCleared + "," + loadedClassesCleared + "," + 
unloadedClassesCleared);
+      }
+    }
+  }
   private static long clearFieldMap(ClassLoaderResolverImpl clri, String 
mapFieldName) throws Exception {
     Field mapField = 
ClassLoaderResolverImpl.class.getDeclaredField(mapFieldName);
     mapField.setAccessible(true);
 
     Map<String,Class> map = (Map<String, Class>) mapField.get(clri);
     long sz = map.size();
-    map.clear();
+    mapField.set(clri, Collections.synchronizedMap(new WeakValueMap()));
     return sz;
   }
 

Reply via email to