You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is a memory leak at Engine in a multi-threading context when the following conditions are met:
Thread number > 1
CSP having more than one solution
Only one solution is retrieved through next()
To Reproduce
To reproduce the issue, here is the following code (based on the SendMoreMoney example code). The code is modified in order to have more than one solution :
Gecode 6.2.0 (issue also exists in the 6.3.0 branch)
Valgrind output
...
==4005193== 2,714,208 (350,816 direct, 2,363,392 indirect) bytes in 1,154 blocks are definitely lost in loss record 11 of 11
==4005193== at 0x4E05045: malloc (vg_replace_malloc.c:381)
==4005193== by 0x155216: alloc (allocator.hpp:80)
==4005193== by 0x155216: ralloc (heap.hpp:358)
==4005193== by 0x155216: operator new (heap.hpp:416)
==4005193== by 0x155216: SendMoreMoney::copy() (send-more-money.cpp:37)
==4005193== by 0x274063: Gecode::Space::_clone() (core.cpp:757)
==4005193== by 0x15E83F: clone (core.hpp:3228)
==4005193== by 0x15E83F: Gecode::Search::Par::DFS<Gecode::Search::NoTraceRecorder>::Worker::run() (dfs.hpp:249)
==4005193== by 0x2792F4: Gecode::Support::Thread::Run::exec() (thread.cpp:60)
==4005193== by 0x2793EE: Gecode::Support::bootstrap(void*) (pthreads.cpp:43)
==4005193== by 0x52D4B42: start_thread (pthread_create.c:442)
==4005193== by 0x5365BB3: clone (clone.S:100)
==4005193==
==4005193== LEAK SUMMARY:
==4005193== definitely lost: 350,816 bytes in 1,154 blocks
==4005193== indirectly lost: 2,363,392 bytes in 1,154 blocks
==4005193== possibly lost: 137,544 bytes in 11 blocks
==4005193== still reachable: 1,256 bytes in 9 blocks
==4005193== suppressed: 0 bytes in 0 blocks
==4005193== Reachable blocks (those to which a pointer was found) are not shown.
Analysis
After a short analysis, I found out that:
In gecode/search/par/engine.hh, the Support::DynamicQueue<Space*,Heap> solutions attribute contains pointers to the solutions that are pushed by workers during the search phase.
The solutions is consumed through the Engine<Tracer>::next(void) method.
If the solutions aren't consumed, the Space* objects remain in the solutions queue. The Space* objects are generated by Space* s = cur->clone(); and pushed to the solutions queue when a solution is found.
At the end of processing, the destructor of the Support::DynamicQueue<Space*, Heap> solutions object frees its memory through a.free(q,limit)
However, unconsumed Space* objects are definitely lost as their references are removed by the previous operation.
Draft solution
To explicitly consume remaining Space* through solution.pop() then delete those objects when the destructor of Engine<Tracer> is called.
The text was updated successfully, but these errors were encountered:
This fix proceeds by cleaning the Gecode::Support::DynamicQueue<Gecode::Space *, Gecode::Heap> solutions attribute of the Gecode::Search::Par::Engine<Tracer> class in the destructor. It unstacks the remaining Gecode::Space * items of the queue and explicitly deletes the objects until the queue is empty.
This fix uses the same mechanism as of gecode/search/par/pbs.hpp
Description
There is a memory leak at Engine in a multi-threading context when the following conditions are met:
next()
To Reproduce
To reproduce the issue, here is the following code (based on the
SendMoreMoney
example code). The code is modified in order to have more than one solution :Compilation with Debug mode:
Platform
Valgrind output
Analysis
After a short analysis, I found out that:
gecode/search/par/engine.hh
, theSupport::DynamicQueue<Space*,Heap> solutions
attribute contains pointers to the solutions that are pushed by workers during the search phase.solutions
is consumed through theEngine<Tracer>::next(void)
method.Space*
objects remain in thesolutions
queue. TheSpace*
objects are generated bySpace* s = cur->clone();
and pushed to thesolutions
queue when a solution is found.Support::DynamicQueue<Space*, Heap> solutions
object frees its memory througha.free(q,limit)
Space*
objects are definitely lost as their references are removed by the previous operation.Draft solution
To explicitly consume remaining
Space*
throughsolution.pop()
thendelete
those objects when the destructor ofEngine<Tracer>
is called.The text was updated successfully, but these errors were encountered: