[jcifs] Memory Leak?

Andy Thomson a10008051 at gmail.com
Thu Sep 17 08:34:28 MDT 2009


Mike,

Seeing a memory leak in the latest jcifs 1.3.12 or it sure looks like one.

This is from a long running process -- typically after about 10 hours it
will error with an out of memory condition.

System has 64GB memory
java -Xmx1024m
jcifs.smb.client.ssnLimit=1

"Exception in thread "Transport414026" java.lang.OutOfMemoryError: Java
heap space"

I happened to grab a heap dump about 11 hours into the latest run,
ironically it ran out of memory shortly afterwards.  What it looks like
is that the connections are never released. More about this after some
of the statistical information from the jhat tool.

Listed below is a partial list containing a count of the all instances
in the dump, this is just the top of the list. After 11 hours of running
there are 304,000+ instances of various jcifs objects.  Notice that the
one of the largest consumers is a LinkedList. These objects account for
739 MB of "retained" memory in this heap dump.

Instance Counts for All Classes (including platform)

1519162 instances of class [Ljava.lang.Object;
1236988 instances of class java.lang.Object
1219633 instances of class java.util.LinkedList$Entry
 630506 instances of class java.lang.String
 630493 instances of class [C
 609819 instances of class java.util.LinkedList
 607371 instances of class [S
 313855 instances of class [B
 312116 instances of class java.net.Inet4Address
 310583 instances of class java.net.Socket
 310583 instances of class java.net.SocksSocketImpl
 305744 instances of class java.lang.ref.Finalizer
 305253 instances of class [Ljava.util.HashMap$Entry;
 305246 instances of class java.util.HashMap
 304934 instances of class java.util.Vector
 304925 instances of class jcifs.smb.SmbComBlankResponse
 304908 instances of class jcifs.smb.SmbTransport
 304908 instances of class jcifs.smb.SmbTransport$ServerData
 304907 instances of class jcifs.UniAddress
 304907 instances of class jcifs.smb.SmbSession
 304907 instances of class jcifs.smb.SmbTree
 302970 instances of class java.net.ConnectException
 302695 instances of class jcifs.util.transport.TransportException

An outline of the code is here, it's not really relevant, more for
reference. It just chains an SmbFile opening a server/share, then a
directory, and finally a file, which is written to using
SmbFileOutputStream.  Everything is in try {} catch {} finally {} blocks
 to make sure nothing escapes :-).  This is most important for the
stream to insure its closed no matter what.

SmbFile targetServer = new SmbFile(machinePath, auth);

  do some stuff

Smbfile targetDirectory =  new SmbFile(smbTargetServer, directory);

  do more stuff

SmbFile smbTargetFile = new SmbFile(smbTargetDir, fileName);

  do even more stuff

SmbFileOutputStream o =null;
  try {
     o = new SmbFileOutputStream(smbTargetFile);
     write();
  catch {
  } finally {
      try {
        o.close();
      catch (Exception ex) {
      }
  }

---

Going back to the heap dump, one of the biggest consumers is a
LinkedList. Drilling into the heap, the entries are from SmbConstants
and the list contains a reference called CONNECTIONS.  Looking at the
source file indicates that there is indeed a LinkedList called CONNECTIONS.

      jcifs.smb.SmbConstants

      static final LinkedList CONNECTIONS = new LinkedList();

Hmm, where is this used at?  Doing a quick search for all occurrences of
 CONNECTIONS on the jcifs code produces only one class, SmbTransport.

All of the references I found were in one method, getSmbTransport()
[lines 43-64], and it only added to the LinkedList.  I could not find
any place where the connections are removed from the LinkedList.
Eventually the list grows to where it consumes enough memory to cause a
java.lang.OutOfMemoryError condition.  The error will appear faster if
the jcifs.smb.client.ssnLimit=1 property is set.

Andy









More information about the jCIFS mailing list