Memory clean after texturize

Hi guys !

I have problem after I'm clean textured objects. I'm create the textured shape with next:

Handle(AIS_TexturedShape) aTShape = new AIS_TexturedShape(aShape);
aTShape->SetTextureFileName(aTFileName);
aTShape->SetTextureMapOn(); //Âêëþ÷àåò mapping
aTShape->SetTextureScale(Standard_True, toScaleU, toScaleV);
aTShape->SetTextureRepeat(Standard_True, toRepeatU, toRepeatV);
aTShape->SetTextureOrigin(Standard_True, 0, 0);
aTShape->DisableTextureModulate();
aTemporaryTextShape.Append(aTShape);
return aTShape;

where the aTemporaryTextShape is AIS_ListOfInteractive.

And then I'm try to clean the textured shape with next:

if (!aTemporaryTextShape.IsEmpty())
{
AIS_ListIteratorOfListOfInteractive aListIterator;
for(aListIterator.Initialize(aTemporaryTextShape);aListIterator.More();aListIterator.Next())
myContext->Erase( aListIterator.Value(), false, false );

aTemporaryTextShape.Clear();
}

Textured shape are is not visible on display, but they are use memory and after I'm create textured objects for 2-3 times I have no free memory.

P.S. I'm install system environment qputenv("MMGT_CLEAR","1"); but nothing result.

JuryS's picture

This problem with Textured Shapes demo too. When I'm click the "R"-retry button for some time I'm have 100% memory usage. 4 Gb

JuryS's picture

This forum is don't working.

Tilman Leune's picture

Memory-leaks are one of the most common issues around here which do only provoke "yeah, i have this problem too!" replies, but no resolving answers.

I have similar trouble with Interactive objects not being released properly ( As you posteed before).

It seems that it is possible to 'outsmart' the memory manager, leaving references to handles nobody needs anymore. It doesn't get better in my project where i built a (closed-source) wrapper-DLL to export OCCT-functionality to an application written in Delphi. Since I pass References to InteractiveObjects back and forth as pointers, i loose memory too.

All the hints on this forum I found did not lead to a solution.

Since these kinds of problems are so common, I would wish for a command like MemoryManager.PurgeAll, with which I could at least free up memory when deinitializing the OCC-Module in my application.

JuryS's picture

Tilman Leune, thanks you have paid attention for this topic! It indeed a serious problem for my application therefore as often it is necessary to include different structures and to litter memory.

I too think of such function, as well as PurgeAll. The system itself cares of clearing of the memory occupied with the application. Therefore now I think to realise application restart hurriedly.

It not the best way, but operating. Or you think that we may use other method? I don't understand how Intel Parallel working, also I don't use M& Windows.

But ! How working other application, any games on OpenGL. I don't see memory-leaks before I'm try to use OCC.

Tilman Leune's picture

I think the problems with 'leaky' OCC-Applications are based on the memory manager the Toolkit provides. It was employed to _avoid_ memory leaking through the implementation of smart pointers. (reference to roman's blog http://opencascade.blogspot.com/2008/11/open-cascade-handles-lets-handle...)

Therefore, other (non OCC) OpenGL-applications do not have these problems.

However, there seems to be a way of using OCC and not having memory leaks, since quite a lot of people on this forum do not complain about it - but maybe their leaks are small or go unnoticed.

Roman Lygin's picture

I don't think OCC memory manager contributes to *real* memory leaks. Its idea is as simple as managing reusable memory chunks. And though they reside under its management, free chunks are still available whenever a new allocation is required.
Just set env variable MMGT_OPT=0 to see how behavior differs.

My own experience with memory leaks which affected me most, was leaks in AIS when displaying AIS_InteractiveObjects (in wireframe and shading). When executing automated units tests in CAD Exchanger that involve importing the models and displaying them in 3D viewer (to make snapshots), the app runs out of memory after running a few hundreds of models (with MMGT_OPT=0). I could not easily root-cause the issue. Intel Parallel Inspector indicates OpenGL routines as leak sources but supposedly the reason is that OCC does not free some display lists or something like that. I don't have deep knowledge of that mechanism, so it's a speculation. Anyway, when you deal with a few models during application life-time these leaks remain unnoticed. But when you deal with hundreds/thousands of models, you can fall a victim of them :-(. Perhaps with textures, as Jury detected, it becomes critical even faster.

Roman

Tilman Leune's picture

Thank you for the input.

I tested my application with MMG_OPT 0 and 1. Some interesting differences occured:

When not using the manager, the first construction of my assembly ate ~30MB of memory. The deletion of the assembly released a meager half MB, and every succesive coonstruction ate about 20 MB.

When the manager is active, The first construction needs about 20 MB, and every successive construction only 7 MB more.

I am downloading the evaluation version of Intels parallel inspector right now to track this issue down.

allocated when my assembly is constructed about (20-30 megs), but almost non of it is free'd.

Tilman Leune's picture

please disregard the last line of my previous post

JuryS's picture

Many Thanks for your participation in the problem decision!
I think that will be difficult to work in Intel Parallel Inspector.

I already see source code of OCC about memory leaks. I try to understand methods Clean, Erase and Remove.

I think that for any objects, not only with texture, at least one of functions should carry out clearing of the allocated memory.

By the way, in a case with structures, in my program for designing of kitchens and other furniture the size of memory on one pass texturing makes ~150 Mb, and also at repeated imposing of a structure, that is memory is filled very quickly.

JuryS's picture

Hi Guys, I'm found two function where the memory is leak.

For the first time and 50%% of memory leak with AddPresentation(aPresentableObject,aMode); in PrsMgr_PresentationManager.cxx

and for the second time with Presentation(aPresentableObject,aMode)->Display(); also 50%% of memory leaks.

I don't see any instruction with MMGT_CLEAR in this functions, also I don't see any function like memory allocation and free method.

I'm think It's a not complete code of OCC and there is more work that I think.

JuryS's picture

I'm FOUND THIS BUG !!!

There is problem with AIS_TexturedShape.cxx !!!

now I'm great the function in header like:
Standard_EXPORT void Clear() ;
and a function:

//=======================================================================
void AIS_TexturedShape::Clear()
{
mytexture->Delete();
}

And all ! No more memory Leak ! after I'm use aTshape->clear();

P Dolbey's picture

OCCPATCH

JuryS's picture

Dolbey, I'm think that my work is not OCCPATCH, because now I'm working on this problem and this problem I'm think with Graphic3d_AspectFillArea3d.

When I'm found how we can RELEASE all memory after texturize, then it's must be a occpatch, but not now.

Roman Lygin's picture

Jury,
Can you elaborate on what are you doing here ?
Calling mytexture->Delete() you simply destroy the object (and of course, apparently frees all the memory it has allocated before). I don't know mechanics of texture mapping but I see at least two issues:
1. AIS_TexturedShape becomes very fragile and may throw an exception in Compute(), Redisplay() as its member-field is destroyed.
2. You should not destroy handles (smart pointers) by calling Delete(). You should rather use mytexture.Nullify() which decrements a counter and if it reaches 0 it will call Delete() itself.

So, your modification probably works for your case as a tweak/hack but cannot be integrated into OCC as is.

Hope this helps.
Roman

JuryS's picture

Delete method don't release any memory. Now when I'm use next with clear() function I'm have 40%% memory released and no more memory leak for this shape on next texturing, but for the next shape I'm have memory leak for the first time texturing and no leaks for the second textured after clear() method:

mytexture->Delete();
mytexture = NULL;

myAspect->Delete();
myAspect = NULL;

mygroup->Clear();
mygroup = NULL;

myTextureFile = NULL;
DoRepeat = NULL;
myURepeat = NULL;
myVRepeat = NULL;
DoMapTexture = NULL;
DoSetTextureOrigin = NULL;
myUOrigin = NULL;
myVOrigin = NULL;
DoSetTextureScale = NULL;
myScaleU = NULL;
myScaleV = NULL;
DoShowTriangles = NULL;
myDeflection = NULL;
Umin = NULL;
Umax = NULL;
Vmin = NULL;
Vmax = NULL;
dUmax = NULL;
dVmax = NULL;
myModulate = NULL;

I'm working now for this problem and I'm try to understand this.

I'm want that all memory after remove Textured shape was released and I'm create new class in my application for Texturize

JuryS's picture

I'm make many test with OCC GraphicDriver and what I see:

when I'm remove the TexturedShape the memory is not released:
for the sample, call_togl_create_texture is running for 10 times,
but call_togl_destroy_texture is not running any time !

But when I use method myAspect->Delete(); the call_togl_destroy_texture is calling 10 times too.

AND WHAT OCC NEED FOR MEMORY RELEASED WITH TEXTURED:

1. In AIS_TexturedShape.hxx uncomment next line:

Standard_EXPORT ~AIS_TexturedShape();

2. In AIS_TexturedShape.cxx create:

AIS_TexturedShape::~AIS_TexturedShape()
{
myAspect->Delete();
}

And that all, no additional method. I'm test this and don't need call any function like aTexturedShape->Delete(), or aTexturedShape->Clear()...
The OCC Viewer is call automaticly method ~AIS_TexturedShape() when you remove the textured shape from context.

And this OCCPATCH !

JuryS's picture

Also I have some bad thinks... In OCC I have ~15.5k of headers files and in all of this the Distruction is commented. And why ? It's only one problem with texturize, but what about another classes ??

Roman Lygin's picture

Jury,

Having no explicit destructor is not a problem by itself. When the destructor is not explicitly provided it is auto-generated. It calls destructors of all member fields and calls destructor of the superclass.
In the case of AIS_TexturedShape, it will nullify all handle fields (including mytexture). If mytexture has reference count=1 when an auto-destructor is called then it decrements to 0 and its Delete() method is called. Enforcing Delete() as you did is dangerous for data integrity as I mentioned yesterday. As far as I can understand the reference count is > 1 when a destructor is called and this forces mytexture reside in memory. (I have described some other similar cases in the blog http://opencascade.blogspot.com/2009/03/unnoticeable-memory-leaks-part-1..., see also Part2).

Try to debug where the reference count gets increased.

The above code will not be accepted as OCC patch, sorry.

Hope this helps.
Roman

JuryS's picture

Roman, thank you. I'm understand all that you say and 6 month ago I read all your blogpost, also I see all your comment on this forum. Some people ask about the help at this forum from you.

And what about memory leaks:
I know that is mytexture->Delete() is not calling anywhere, because the opengl texture destroy mechanism is don't calling anytime.

Also I see that OCC is not destroy created textures and pixmaps for any created AIS_TexturedObjects. It's no bad idea, because for some time when you calling texturize the textures is don't created after first time.

BUT I want create the function that is clear all memory. I may create the function witch restart my application any time when there is no free memory, but this is not good way.

Or I need found all collectors that OCC is create, for texturize, for boolean operation, after remove objects, more other ... and clean that all.

It's like the program restart and return default viewer values for current opened document.
Or some function like CLEAR_COLLECTORS for release all memory.

I'm see that application based on OCC used utilities like starter or wrappers. I see that NaroCAD has no any memory leaks. But there is more problem under M& Windows /and no problem with Linux or MAC/.

JuryS's picture

Also in OpenGl_GraphicDriver_9.cxx the IMP131100 must be removed.

Because if IMP131100 is defined the opengl texture COLLECTOR is don't working.

It's must be:

Standard_CString fileName = FileName;

JuryS's picture

I make my implementation of AIS_TexturedObject and I don't have any leaks.

And I try to understand why OCC have this problem. And what is a la - oopengl driver ? Who is input this in OCC ???