Memory leak Sicstus Prolog
Asked Answered
G

3

5

This question is a followup from this question.

I'm running a large number of tests in Sicstus prolog:

runtest:-
 t1,
 t2,
 t3,
 .
 .
 t100.

Each test is standalone and will print its result to the screen. There is no releation between the tests, so no data need to be stored/saved between each test.

My problem is that Sicstus accumulates memory and finally hits an exception: 'Resource error: insufficient memory'

I have tried to organize my test like this:

runtest:-
  once( t1 ),
  once( t2 ),
  .
  .
  once( t100 ).

But I still get into the problem.

Is there any other way to tell Prolog to free all allocated memory between each call to a test?

Gladstone answered 12/2, 2014 at 7:11 Comment(0)
R
5

No, there is no way to tell Prolog to free all allocated memory.

If the test predicates takes no arguments, and wrapping them in once/1 does not help, then a failure driven loop also should not help.

One possibility is that your tests somehow add persistent data, e.g. asserts clauses.

Try adding

garbage_collect, statistics

between (some of) the test. This should give you an idea about which memory areas are growing.

From looking at your earlier question, it could be that one of your tests runs out of memory all by itself, i.e. that the problem is unrelated to running multiple tests.

Railhead answered 12/2, 2014 at 10:32 Comment(1)
undo might be another reason why once/1 cannot reclaim space.Menderes
H
3

Try using a (modern) failure driven loop: should reclaim memory on any Prolog

?- forall(member(T, [t1,t2,...,t100]), once(T)).
Hildick answered 12/2, 2014 at 8:58 Comment(2)
It would help a lot to terminologically separate this style from the common failure driven loops. findall/3, setof/3 have failure driven loops inside.Menderes
There is no need for once(T) because T suffices.Menderes
B
2

The predicate once/1 only cuts away choice points, but leaves intact the trail. The trail is usually extended either by variable unifications or even by constraints of the constraint solvers.

So your chain of tests collects a lot of data. There is a Prolog folklore which would help you. Using double negation frees resources, this construct is therefore often nicknamed garbage collection.

Just rewrite your code to:

runtest:-
   \+ \+ t1,
   \+ \+ t2,
   \+ \+ t3,
   .
   .
   \+ \+ t100.

But please note that your test will now also measure the time to tear down the trail, possibly changing old results, since sometime the time to tear down the trail can be measurable.

And last but not least, of course the folklore garbage collection double negation only works when it is ok to call the goal once.

Bye

Booster answered 1/11, 2015 at 1:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.