[jboss-cvs] JBossAS SVN: r91858 - projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jul 30 21:41:54 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-07-30 21:41:53 -0400 (Thu, 30 Jul 2009)
New Revision: 91858

Modified:
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java
Log:
Show an allocation stack trace when mounts are leaked

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java	2009-07-31 01:41:27 UTC (rev 91857)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java	2009-07-31 01:41:53 UTC (rev 91858)
@@ -43,11 +43,15 @@
 import java.util.zip.ZipEntry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 import org.jboss.virtual.spi.FileSystem;
 import org.jboss.virtual.spi.RealFileSystem;
 import org.jboss.virtual.spi.JavaZipFileSystem;
 import org.jboss.virtual.plugins.vfs.helpers.PathTokenizer;
+import org.jboss.logging.Logger;
 
 /**
  * Virtual File System
@@ -59,6 +63,10 @@
  */
 public class VFS
 {
+   private static final Logger log = Logger.getLogger(VFS.class);
+
+   public static final boolean LEAK_DEBUGGING;
+
    private final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = new ConcurrentHashMap<VirtualFile, Map<String, Mount>>();
    private final VirtualFile rootVirtualFile;
    private final Mount rootMount;
@@ -70,6 +78,13 @@
    static
    {
       init();
+      LEAK_DEBUGGING = AccessController.doPrivileged(new PrivilegedAction<Boolean>()
+      {
+         public Boolean run()
+         {
+            return Boolean.valueOf(System.getProperty("jboss.vfs.leakDebugging", "true"));
+         }
+      }).booleanValue();
    }
 
    /**
@@ -634,15 +649,21 @@
    final class Mount implements Closeable {
       private final FileSystem fileSystem;
       private final VirtualFile mountPoint;
+      private final StackTraceElement[] allocationPoint;
+      private final AtomicBoolean closed = new AtomicBoolean(false);
 
       Mount(FileSystem fileSystem, VirtualFile mountPoint)
       {
          this.fileSystem = fileSystem;
          this.mountPoint = mountPoint;
+         allocationPoint = Thread.currentThread().getStackTrace();
       }
 
       public void close() throws IOException
       {
+         if (closed.getAndSet(true)) {
+            return;
+         }
          final String name = mountPoint.getName();
          final VirtualFile parent = mountPoint.getParent();
          final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = VFS.this.mounts;
@@ -691,5 +712,29 @@
       {
          return mountPoint;
       }
+
+      protected void finalize() throws IOException
+      {
+         if (! closed.get()) {
+            final StackTraceElement[] allocationPoint = this.allocationPoint;
+            if (allocationPoint != null) {
+               final LeakDescriptor t = new LeakDescriptor();
+               t.setStackTrace(allocationPoint);
+               log.warnf(t, "A VFS mount (%s) was leaked!", mountPoint);
+            } else {
+               log.warnf("A VFS mount (%s) was leaked!", mountPoint);
+            }
+            close();
+         }
+      }
    }
+
+   private static final class LeakDescriptor extends Throwable {
+      private static final long serialVersionUID = 6034058126740270584L;
+
+      public String toString()
+      {
+         return "Allocation stack trace:";
+      }
+   }
 }




More information about the jboss-cvs-commits mailing list