ソースを参照

HDFS-12984. BlockPoolSlice can leak in a mini dfs cluster. Contributed by Ajay Kumar.

Arpit Agarwal 7 年 前
コミット
b278f7b293

+ 15 - 8
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/BlockPoolSlice.java

@@ -84,6 +84,7 @@ class BlockPoolSlice {
   private final int ioFileBufferSize;
   private final int ioFileBufferSize;
   @VisibleForTesting
   @VisibleForTesting
   public static final String DU_CACHE_FILE = "dfsUsed";
   public static final String DU_CACHE_FILE = "dfsUsed";
+  private final Runnable shutdownHook;
   private volatile boolean dfsUsedSaved = false;
   private volatile boolean dfsUsedSaved = false;
   private static final int SHUTDOWN_HOOK_PRIORITY = 30;
   private static final int SHUTDOWN_HOOK_PRIORITY = 30;
   private final boolean deleteDuplicateReplicas;
   private final boolean deleteDuplicateReplicas;
@@ -162,15 +163,16 @@ class BlockPoolSlice {
                                                      .build();
                                                      .build();
 
 
     // Make the dfs usage to be saved during shutdown.
     // Make the dfs usage to be saved during shutdown.
-    ShutdownHookManager.get().addShutdownHook(
-      new Runnable() {
-        @Override
-        public void run() {
-          if (!dfsUsedSaved) {
-            saveDfsUsed();
-          }
+    shutdownHook = new Runnable() {
+      @Override
+      public void run() {
+        if (!dfsUsedSaved) {
+          saveDfsUsed();
         }
         }
-      }, SHUTDOWN_HOOK_PRIORITY);
+      }
+    };
+    ShutdownHookManager.get().addShutdownHook(shutdownHook,
+        SHUTDOWN_HOOK_PRIORITY);
   }
   }
 
 
   File getDirectory() {
   File getDirectory() {
@@ -756,6 +758,11 @@ class BlockPoolSlice {
     saveDfsUsed();
     saveDfsUsed();
     dfsUsedSaved = true;
     dfsUsedSaved = true;
 
 
+    // Remove the shutdown hook to avoid any memory leak
+    if (shutdownHook != null) {
+      ShutdownHookManager.get().removeShutdownHook(shutdownHook);
+    }
+
     if (dfsUsage instanceof CachingGetSpaceUsed) {
     if (dfsUsage instanceof CachingGetSpaceUsed) {
       IOUtils.cleanup(LOG, ((CachingGetSpaceUsed) dfsUsage));
       IOUtils.cleanup(LOG, ((CachingGetSpaceUsed) dfsUsage));
     }
     }