Some uses of SPTerm
will leak memory on the Prolog side. This
happens if a new SPTerm
object is allocate, but Java neither
returns to Prolog nor backtracks (using the method close
,
cut
or nextSolution
) into a query opened before the
allocation of the SPTerm
object.
As of SICStus 3.8.5, it is possible to explicitly delete a SPTerm
object using the SPTerm.delete()
method. The delete()
method invalidates the SPTerm object and makes the associated
SP_term_ref available for re-use.
Another way to ensure that all SP_term_refs are deallocated is to open a dummy query only for this purpose. The following code demonstrates this:
// Always synchronize over creation and closing of SPQuery objects synchronized (sp) { // Create a dummy query that invokes true/0 SPQuery context = sp.openQuery("user","true",new SPTerm[]{}); // All SP_term_refs created after this point will be reclaimed by // Prolog when doing context.close() (or context.cut()) try { // ensure context is always closed SPTerm tmp = new SPTerm(sp); // created after context int i = 0; while (i++ < 5) { // re-used instead of doing tmp = new SPTerm(sp,"..."); tmp.putString("Iteration #" + i + "\n"); // e.g. user:write('Iteration #1\n') sp.queryCutFail("user", "write", new SPTerm[]{tmp}); } } finally { // This will invalidate tmp and make Prolog // reclaim the corresponding SP_term_ref context.close(); // or context.cut() to retain variable bindings. } }