Preventing SPTerm Memory Leaks

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.

Send feedback on this subject.