You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by kh...@apache.org on 2017/03/16 18:35:22 UTC
hive git commit: HIVE-16160 : OutOfMemoryError: GC overhead limit
exceeded on Hiveserver2 (Sushanth Sowmyan, reviewed by Daniel Dai)
Repository: hive
Updated Branches:
refs/heads/master 2f1d4b11e -> 4cb87670e
HIVE-16160 : OutOfMemoryError: GC overhead limit exceeded on Hiveserver2 (Sushanth Sowmyan, reviewed by Daniel Dai)
Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/4cb87670
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/4cb87670
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/4cb87670
Branch: refs/heads/master
Commit: 4cb87670ef416f86aca94b38270527f636fd4dcc
Parents: 2f1d4b1
Author: Sushanth Sowmyan <kh...@gmail.com>
Authored: Thu Mar 16 11:28:05 2017 -0700
Committer: Sushanth Sowmyan <kh...@gmail.com>
Committed: Thu Mar 16 11:35:18 2017 -0700
----------------------------------------------------------------------
.../hadoop/hive/metastore/ObjectStore.java | 60 ++++++++++++++++----
1 file changed, 49 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hive/blob/4cb87670/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 c3f2e99..6a23edf 100644
--- a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java
+++ b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java
@@ -156,6 +156,7 @@ import org.apache.hive.common.util.HiveStringUtils;
import org.apache.thrift.TException;
import org.datanucleus.AbstractNucleusContext;
import org.datanucleus.ClassLoaderResolver;
+import org.datanucleus.ClassLoaderResolverImpl;
import org.datanucleus.NucleusContext;
import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
import org.datanucleus.store.rdbms.exceptions.MissingTableException;
@@ -279,6 +280,9 @@ public class ObjectStore implements RawStore, Configurable {
boolean propsChanged = !propsFromConf.equals(prop);
if (propsChanged) {
+ if (pmf != null){
+ clearOutPmfClassLoaderCache(pmf);
+ }
pmf = null;
prop = null;
}
@@ -8443,21 +8447,55 @@ public class ObjectStore implements RawStore, Configurable {
*/
public static void unCacheDataNucleusClassLoaders() {
PersistenceManagerFactory pmf = ObjectStore.getPMF();
- if ((pmf != null) && (pmf instanceof JDOPersistenceManagerFactory)) {
- JDOPersistenceManagerFactory jdoPmf = (JDOPersistenceManagerFactory) pmf;
- NucleusContext nc = jdoPmf.getNucleusContext();
- try {
- Field classLoaderResolverMap = AbstractNucleusContext.class.getDeclaredField(
- "classLoaderResolverMap");
- classLoaderResolverMap.setAccessible(true);
- classLoaderResolverMap.set(nc, new HashMap<String, ClassLoaderResolver>());
- LOG.debug("Removed cached classloaders from DataNucleus NucleusContext");
- } catch (Exception e) {
- LOG.warn("Failed to remove cached classloaders from DataNucleus NucleusContext ", e);
+ clearOutPmfClassLoaderCache(pmf);
+ }
+
+ private static void clearOutPmfClassLoaderCache(PersistenceManagerFactory pmf) {
+ if ((pmf == null) || (!(pmf instanceof JDOPersistenceManagerFactory))) {
+ return;
+ }
+ // NOTE : This is hacky, and this section of code is fragile depending on DN code varnames
+ // so it's likely to stop working at some time in the future, especially if we upgrade DN
+ // versions, so we actively need to find a better way to make sure the leak doesn't happen
+ // instead of just clearing out the cache after every call.
+ JDOPersistenceManagerFactory jdoPmf = (JDOPersistenceManagerFactory) pmf;
+ NucleusContext nc = jdoPmf.getNucleusContext();
+ try {
+ 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);
+ }
+ }
}
+ classLoaderResolverMap.set(nc, new HashMap<String, ClassLoaderResolver>());
+ LOG.debug("Removed cached classloaders from DataNucleus NucleusContext");
+ } catch (Exception e) {
+ LOG.warn("Failed to remove cached classloaders from DataNucleus NucleusContext ", e);
}
}
+ 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();
+ return sz;
+ }
+
+
@Override
public List<SQLPrimaryKey> getPrimaryKeys(String db_name, String tbl_name) throws MetaException {
try {