Outrigger memory leak?

Greg Trasuk <[email protected]> Tue, 2 Jan 2007 17:11:23 -0500
Newsgroups gmane.comp.java.sun.javaspaces
Message-ID <1167775883.3003.41.camel@cameron>
Hi all:

        I'm running up against out-of-memory errors using transient outrigger.
I got the errors in a production system that runs a fair bit of data
through the space, then wrote a test script to try and isolate the
problem (code attached below).  When running with max heap size at the
default (512M, I believe), the Outrigger instance runs out of heap after
about 2100 iterations with a payload size of 250e3 bytes.  With smaller
payloads, I get more iterations (although curiously not in any kind of
linear relationship.  hmmm...), but I still get the failure eventually.

        Note that the test case verifies that the entry is gone after I 'take'
it.  I've also confirmed in other tests that it disappears on its own
when the lease time expires, so everything seems to be behaving as
expected.  Letting the space sit idle for a short time between accesses
also has no effect (I wondered if perhaps the reaping thread didn't get
a chance to run).  I've tried setting 'reapingInterval=5000;
reapingPriority=Thread.MAX_PRIORITY', which had no effect.

        Am I missing something in the configuration?  The problem is
independent of whether Outrigger is run under Harvester or from the
Launch-All script in the starter kit.  I haven't found any other bug
reports, and I find it hard to believe I've found a bug in a mature
product.  Any suggestions?

Thanks in advance,

Greg.

Environment details:
--------------------
JSK 2.1
JDK 1.5.0_09 Server VM on Solaris 10 (same issue on Windows XP running
JDK6)
Opteron 165 Processor (dual-core), 2GB physical memory

Test Case (run in a different VM from Outrigger):
-------------------------------------------------
public class TestSpace extends TestCase {

    private static final int PAYLOAD_SIZE=250000;

    /** Creates a new instance of TestSpace */
    public TestSpace(String s) {
        super(s);
    }

    private ApplicationContext applicationContext=null;
    private JavaSpace space=null;

    public void setUp() {
        setApplicationContext(StaticApplicationContext.getContext());
    }

    /** We should be able to create an entry, drop it in and retrieve
it. */
    public void testSpace() throws Exception {
        DynamicResolver resolver=new DynamicResolver(this);
        try {

            resolver.resolve();
            assertTrue("No JavaSpace was found", getSpace()!= null);

            SampleEntry entry = new SampleEntry();
            entry.uuid=UuidFactory.generate();
            byte[] payload=new byte[PAYLOAD_SIZE];
            entry.payload=payload;

            getSpace().write(entry, null, 5000);
            entry.payload=null;

            SampleEntry retrievedEntry=(SampleEntry)
getSpace().takeIfExists(entry, null, JavaSpace.NO_WAIT);
            assertTrue("Didn't get my entry back",
retrievedEntry!=null);
            assertTrue("Didn't get the payload back",
retrievedEntry.payload!=null);
            byte[] retrievedPayload=(byte[]) retrievedEntry.payload;
            assertTrue("Payload size wasn't right.",
retrievedPayload.length==payload.length);
            /* Once we have retrieved it, it should not be retrievable
again. */
            retrievedEntry=(SampleEntry) getSpace().takeIfExists(entry,
null, JavaSpace.NO_WAIT);
            assertTrue("Entry was still there after I took it",
retrievedEntry==null);
        } catch(RuntimeException ex) {
            resolver.fail();
            throw ex;
        } catch(Exception t) {
            resolver.fail();
            throw t;
        } finally {
            resolver.clear();
        }
    }

    public void testSpaceALot() throws Exception {
        int i=0;
        try {
            for(i=0; i <5000; i++) {
                testSpace();
            }
        } catch(Exception ex) {
            fail("Exception " + ex.getMessage() + " at " + i + "
iterations and payload size=" + PAYLOAD_SIZE+ ".");
        }
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext
applicationContext) {
        this.applicationContext = applicationContext;
    }

    public JavaSpace getSpace() {
        return space;
    }

    public void setSpace(JavaSpace space) {
        this.space = space;
    }
}
--
Greg Trasuk, President
StratusCom Manufacturing Systems Inc. - We use information technology to
solve business problems on your plant floor.
http://stratuscom.com

===========================================================================
To unsubscribe, send email to [email protected] and include in the body
of the message "signoff JAVASPACES-USERS".  For general help, send email to
[email protected] and include in the body of the message "help".

To view past JAVASPACES-USERS postings, please see:
http://archives.java.sun.com/archives/javaspaces-users.html