Memory leaks in SMESH ?
Hello,
I am starting first steps with development using Salome (via the SMESH project at sourceforge which is based on 5.1.2).
The very first code:
boost::shared_ptr<SMESH_Gen> aGen (new SMESH_Gen());
boost::shared_ptr<SMESH_Mesh> aMesh (aGen->CreateMesh (0, true));
reveals memory leaks – many destructors of the internally created objects are just not called. For instance, empty destructor of SMESH_Gen does not destroy elements in _mapStudyContext, SMESH_Mesh destructor does not destroy its _myMeshDS and so on.
Here is the debug output:
- Trace ..\..\src\SMESH\SMESH_Gen.cpp [53] : SMESH_Gen::SMESH_Gen
- Trace ..\..\src\SMESH\SMESH_Gen.cpp [109] : SMESH_Gen::CreateMesh
- Trace ..\..\src\SMESH\SMESH_Mesh.cpp [89] : SMESH_Mesh::SMESH_Mesh(int localId)
- Trace ..\..\src\SMESH\SMESH_Mesh.cpp [110] : SMESH_Mesh::~SMESH_Mesh
- Trace ..\..\src\SMESH\SMESH_Gen.cpp [67] : SMESH_Gen::~SMESH_Gen
I have not run memory analysis with Intel Parallel Inspector to confirm suspicion but am pretty sure it will report leaks as, for instance, a breakpoint in destructor of SMESHDS_Mesh is not reached.
This sort of issues should have been caught years ago, so I rather assume I am making some mistakes, though two lines of the code above looks pretty straightforward too.
Does anybody have any clue on the issue?
Thank you in advance,
Roman
Hi Roman
In SMESH, there is a higher level in the hierarchy of objects (SMESH_SRC/src/SMESH_I/*) that arranges the life cycle of the mesh according to application events. The mesh is explicitly destroyed when a dedicated study object dies.
Regards
Hi EAP (Edward?),
Thank you for the explanation and the reference. I have briefly looked into the SMESH_Gen_i and see that it brings some Corba-like overhead, which would be overwhelming in a non-Salome application. (I am currently investigating SMEH for CAD Exchanger). Secondly, SMESH_I is not part of the smesh project at Sourceforge (which is a subset of Salome) and Salome itself is not officially ported on Windows yet (though there is an experimental build from Erwan Adam).
So at this point, I a bit hesitate to step into the SMESH_I area. I will try to see what is possible to deal at the minimum level, perhaps looking at SMESH_I as a reference.
Thanks again,
Roman
Running very basic code given here (http://salome-platform.org/forum/forum_11/257023341) on a shape attached in the same thread under Intel Parallel Inspector XE revealed memory leaks, as expected
.
A couple of examples:
1. SMESH_subMesh *SMESH_Mesh::GetSubMesh()
aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
_mapSubMesh[index] = aSubMesh;
_mapSubMesh is never destroyed and hence all submeshes leak.
Given reference to SMESH_I above, I can't see how it can prevent leaks here. Sub-meshes are fully owned by SMESH_Mesh, so why would any external reference help ? Why isn't it part of the destructor?
Failure to destroy submeshes lead to other leaks related to resources controlled by submeshes (e.g. event listeners), e.g. allocated as follows:
void PropagationMgr::Set(SMESH_subMesh * submesh)
{
EventListenerData* data = new PropagationMgrData();
submesh->SetEventListener( getListener(), data, submesh );
Overall reading of Salome code and above memory leaks begs the following question. Why are plain pointers used in majority of places where smart pointers (boost::shared_ptr) would be a more reliable solution? This would eliminate needs to explicitly call delete and thus avoid head-ache of manual destruction.
Open CASCADE has been using handle (Handle_Standard_Transient subclasses) to reliably manage memory. Why did not Salome adopt similar approach with boost::shared_ptr ?
Thank you,
Roman
