Re: Memory leaks in 2.01

Michael Reinhardt <[email protected]>
Newsgroups gmane.comp.video.openexr.devel
Message-ID <[email protected]>
Hi,

if it is convenient for you to call a single method upon unloading, my 
patch might help you. You have to call 
"OPENEXR_IMF_NAMESPACE::staticUninitialize();" (I know, this is not the 
best name for it.) when you want to unload the library. It will delete 
the typemap and kill the memory leak. It works flawless in my 
application, but I can't guarantee that it will work in every situation. 
;-) What I want to say: This is a quick hack. There might be bugs inside.

Michael

P.s.: I had to adjust the file structure of the IlmImf library, so the 
file paths in the patch file won't fit.

Am 04.11.2013 16:17, schrieb Juri Abramov:
>
> *Note that if someone builds a plugin around OpenEXR library and 
> unloads it, the memory leak is there. It is small, and mostly just 
> annoying as one needs to add exceptions for memory leak hunting tools. 
> It would be great to have some clean function/method.*
>
> **
>
> *Juri*
>
> **
>
> *From:*[email protected] 
> [mailto:[email protected]] *On 
> Behalf Of *Michael Reinhardt
> *Sent:* 04 November, 2013 15:58
> *To:* OpenEXR Devel List
> *Subject:* Re: [Openexr-devel] Memory leaks in 2.01
>
> Hi Gerhard,
>
> I don't think you encountered a real memory leak. It just looks like 
> one. (I stumbled upon this "leak" some time ago ;-) ). Upon creating a 
> file - or something else that can handle Header object - a function 
> named staticInitialize() (ImfHeader.h) is called. This function 
> registers the basic attributes (e.g. Double, String, ...). These basic 
> attributes are stored inside a static variable of the type 
> LockedTypeMap (ImfAttribute.c). Afterwards, they are not touched 
> again. The registration remains until the process ends. This is 
> expected behaviour in my opinion. (Initialization is done once.)
> Since the container for the basic attributes is a "function static  
> variable", it will be deleted upon exit of the calling process. (As 
> all remaining memory allocations will do.)
>
> This memory is allocated once. There is no growing runtime leak. Your 
> memory leak detector is getting angry, because it checks the memory 
> map too early. This "lazy static initialization" isn't recognized by 
> the mem checker.
>
> IMHO, there is no way to circumvent this behaviour without having to 
> initialize the typemap with every creation of an FileObject. And 
> that's not very performant.
>
> I hope, I could allay your concerns.
>
> Michael
>
> Am 04.11.2013 08:04, schrieb Gerhard Huber:
>
>     Hi,
>
>     when I just create in InputFile
>                     EXRReadFile    exrFile(file);
>                     InputFile    inFile(exrFile);
>     I get some memory leaks. I think the problem are some unreleased
>     Attributes. The size of the memory leaks is almost 48 Bytes and
>     one with 104 Bytes.
>
>     Gerhard
>
>
>
>
>     _______________________________________________
>
>     Openexr-devel mailing list
>
>     [email protected]  <mailto:[email protected]>
>
>     https://lists.nongnu.org/mailman/listinfo/openexr-devel
>
> ----------
> visit us at
>
>   
> Medica 2013 / Duesseldorf, Germany /20-23 November / hall 16-D54
>
> ------------------------------------------------------------------------
> This email message is for the sole use of the intended recipient(s) 
> and may contain confidential information.  Any unauthorized review, 
> use, disclosure or distribution is prohibited.  If you are not the 
> intended recipient, please contact the sender by reply email and 
> destroy all copies of the original message.
> ------------------------------------------------------------------------


----------
visit us at

Medica 2013 / Duesseldorf, Germany /20-23 November / hall 16-D54

_______________________________________________
Openexr-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/openexr-devel
Uninit.patch (text/plain, 2.7 KB)
Index: include/OpenEXR/ImfAttribute.h
===================================================================
--- include/OpenEXR/ImfAttribute.h	(revision 169)
+++ include/OpenEXR/ImfAttribute.h	(working copy)
@@ -106,7 +106,12 @@
 
     static bool            knownType (const char typeName[]);
 
+    //------------------------------------------------------
+    // Un-register all known attributes.
+    //------------------------------------------------------
 
+    static void clearAttributeRegistration();
+
   protected:
 
     //--------------------------------------------------
Index: include/OpenEXR/ImfHeader.h
===================================================================
--- include/OpenEXR/ImfHeader.h	(revision 169)
+++ include/OpenEXR/ImfHeader.h	(working copy)
@@ -493,6 +493,7 @@
 //------------------------------------------------------------------------
 
 void staticInitialize ();
+void staticUninitialize ();
 
 
 //-----------------
Index: src/lib/IlmImf/ImfAttribute.cpp
===================================================================
--- src/lib/IlmImf/ImfAttribute.cpp	(revision 169)
+++ src/lib/IlmImf/ImfAttribute.cpp	(working copy)
@@ -83,22 +83,32 @@
     Mutex mutex;
 };
 
+static Mutex criticalSection;
+static LockedTypeMap* typeMapVar = 0;
 
 LockedTypeMap &
 typeMap ()
 {
-    static Mutex criticalSection;
     Lock lock (criticalSection);
 
-    static LockedTypeMap* typeMap = 0;
+    if (typeMapVar == 0)
+    typeMapVar = new LockedTypeMap ();
 
-    if (typeMap == 0)
-    typeMap = new LockedTypeMap ();
+    return *typeMapVar;
+}
 
-    return *typeMap;
+void
+clearTypeMap ()
+{
+    Lock lock (criticalSection);
+
+    if (typeMapVar != 0)
+    {
+        delete typeMapVar;
+        typeMapVar = 0;
+    }
 }
 
-
 } // namespace
 
 
@@ -137,7 +147,16 @@
     tMap.erase (typeName);
 }
 
+void
+  Attribute::clearAttributeRegistration ()
+{
+    LockedTypeMap& tMap = typeMap();
+    Lock lock (tMap.mutex);
 
+    tMap.clear ();
+    clearTypeMap();
+}
+
 Attribute *
 Attribute::newAttribute (const char typeName[])
 {
Index: src/lib/IlmImf/ImfHeader.cpp
===================================================================
--- src/lib/IlmImf/ImfHeader.cpp	(revision 169)
+++ src/lib/IlmImf/ImfHeader.cpp	(working copy)
@@ -1229,15 +1229,14 @@
     }
 }
 
+static bool initialized = false;
+static Mutex criticalSection;
 
 void
 staticInitialize ()
 {
-    static Mutex criticalSection;
     Lock lock (criticalSection);
 
-    static bool initialized = false;
-
     if (!initialized)
     {
       //
@@ -1277,5 +1276,14 @@
     }
 }
 
+void
+staticUninitialize ()
+{
+    Lock lock (criticalSection);
 
+    Attribute::clearAttributeRegistration();
+
+    initialized = false;
+}
+
 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.