[mapguide-internals] Memory leakage in WebTier (Java)

Walt Welton-Lair walt.welton-lair at autodesk.com
Thu Sep 2 13:54:30 EDT 2010


swigCMemOwn=false is the problem....


Here's the implementation of MgByteSource.GetReader in the SWIG generated .NET version of the API:

public MgByteReader GetReader()
{
    IntPtr cPtr = FoundationApiPINVOKE.MgByteSource_GetReader(swigCPtr);
    return (cPtr == IntPtr.Zero) ? null : (MgByteReader)FoundationApiPINVOKE.createObject(FoundationApiPINVOKE.getClassId(cPtr), FoundationApiPINVOKE.getNameSpace(cPtr), FoundationApiPINVOKE.getClassName(cPtr), cPtr, true);
}

Notice the last argument to FoundationApiPINVOKE.createObject is true - this corresponds to the swigCMemOwn value.  When the MgByteReader is GC'ed, if swigCMemOwn is true then the unmanaged C++ object is released:

~MgByteReader() {
    Dispose();
  }

public override void Dispose() {
    if(swigCPtr != IntPtr.Zero && swigCMemOwn) {
      swigCMemOwn = false;
      FoundationApiPINVOKE.delete_MgByteReader(swigCPtr);
    }
    swigCPtr = IntPtr.Zero;
    GC.SuppressFinalize(this);
    base.Dispose();
}

The call to FoundationApiPINVOKE.delete_MgByteReader is where the unmanaged C++ reader is released.  (Note that once the last reference to the reader is released it will also release its reference to the source object.)


Now look at the implementation of  MgByteSource.GetReader in Java:

public MgByteReader GetReader() throws MgException  {
    long cPtr = MapGuideJavaApiJNI.MgByteSource_GetReader(swigCPtr);
    return (cPtr == 0) ? null : (MgByteReader)ObjectFactory.createObject(MapGuideJavaApiJNI.getClassId(cPtr), cPtr, false);
}

The last argument - which determines what swigCMemOwn gets set to - is false.  Ooooops...

I did a search and all calls to ObjectFactory.createObject pass in false.  So *every* unmanaged object ends up getting leaked if you use the Java API.

Wow - that's a major bug.  Ooooops again...

Walt

-----Original Message-----
From: mapguide-internals-bounces at lists.osgeo.org [mailto:mapguide-internals-bounces at lists.osgeo.org] On Behalf Of Andreas Morf
Sent: Thursday, September 02, 2010 10:40 AM
To: 'MapGuide Internals Mail List'
Subject: RE: [mapguide-internals] Memory leakage in WebTier (Java)

Walt,
Indeed it doesn't - in both cases: the layerDefContent object is not owned by java (ie. swigCMemOwn=false because it is provided by
C++ layer by ::GetReader) so just the java object is destroyed and no delete-call is made to the C++ layer.
But even if the MgByteReader-C++ object would have been destroyed, I cannot see (in the code) where the final reference to the 'src'
C++ object is released and 'src' is destroyed...

Andreas


> -----Original Message-----
> From: mapguide-internals-bounces at lists.osgeo.org [mailto:mapguide-internals-bounces at lists.osgeo.org]
> On Behalf Of Walt Welton-Lair
> Sent: Thursday, September 02, 2010 4:06 PM
> To: MapGuide Internals Mail List
> Subject: RE: [mapguide-internals] Memory leakage in WebTier (Java)
> 
> Why should the GC order matter at all?
> 
> - case 1: src gets GC'ed first, followed by layerDefContent
>         When the src gets GC'ed the ref count of the associated C++ object drops back to one - no C++
> objects are yet destroyed.  Then when the layerDefContent object gets GC'ed the ref count for its C+
> object goes to zero and it gets destroyed, which in turn will release the final reference to the src
> C++ object and it will also get destroyed.
> 
> - case 2: layerDefContent gets GC'ed first, followed by src
>         When the layerDefContent gets GC'ed the ref count for its C+ object goes to zero and it gets
> destroyed, and the ref count of the src C++ object drops back to one.  Then when the src object gets
> GC'ed the ref count for the src C+ object goes to zero and it also gets destroyed.
> 
> 
> It seems like some of the managed objects are not getting GC'ed, which in turn is causing the
> underlying C++ objects to not be destroyed.
> 
> Walt
> 

_______________________________________________
mapguide-internals mailing list
mapguide-internals at lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/mapguide-internals


More information about the mapguide-internals mailing list