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 release 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.
}
}