From: <tho...@us...> - 2011-05-31 12:25:42
|
Revision: 4577 http://bigdata.svn.sourceforge.net/bigdata/?rev=4577&view=rev Author: thompsonbry Date: 2011-05-31 12:25:32 +0000 (Tue, 31 May 2011) Log Message: ----------- Modified the memory leak / finalizer stress tests to maintain weak references to the journals. The weak references are used to ensure that the journals are destroyed by the end of the test in order to avoid side effects on follow on unit tests from lazy finalization of journals created during these stress tests. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestQueryEngineFactory.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestJournalShutdown.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestQueryEngineFactory.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestQueryEngineFactory.java 2011-05-31 10:46:52 UTC (rev 4576) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/fed/TestQueryEngineFactory.java 2011-05-31 12:25:32 UTC (rev 4577) @@ -27,6 +27,7 @@ package com.bigdata.bop.fed; +import java.lang.ref.WeakReference; import java.util.Properties; import junit.framework.TestCase2; @@ -96,15 +97,15 @@ /** * Look for a memory leak in the {@link QueryEngineFactory}. * - * @throws InterruptedException + * @throws InterruptedException */ public void test_memoryLeak() throws InterruptedException { -// // This test currently fails.... -// fail("See https://sourceforge.net/apps/trac/bigdata/ticket/196."); + // This test currently fails.... [this has been fixed.] + // fail("See https://sourceforge.net/apps/trac/bigdata/ticket/196."); final int limit = 200; - + final Properties properties = new Properties(); properties.setProperty(Journal.Options.BUFFER_MODE, @@ -115,53 +116,83 @@ int ncreated = 0; + /* + * An array of weak references to the journals. These references will + * not cause the journals to be retained. However, since we can not + * force a major GC, the non-cleared references are used to ensure that + * all journals are destroyed by the end of this test. + */ + final WeakReference<Journal>[] refs = new WeakReference[limit]; + try { - for (int i = 0; i < limit; i++) { + try { - Journal jnl = new Journal(properties); + for (int i = 0; i < limit; i++) { - // does not exist yet. - assertNull(QueryEngineFactory.getExistingQueryController(jnl)); - - // was not created. - assertNull(QueryEngineFactory.getExistingQueryController(jnl)); - - final QueryEngine queryEngine = QueryEngineFactory.getQueryController(jnl); - - // still exists and is the same reference. - assertTrue(queryEngine == QueryEngineFactory.getExistingQueryController(jnl)); + final Journal jnl = new Journal(properties); - ncreated++; + refs[i] = new WeakReference<Journal>(jnl); + // does not exist yet. + assertNull(QueryEngineFactory + .getExistingQueryController(jnl)); + + // was not created. + assertNull(QueryEngineFactory + .getExistingQueryController(jnl)); + + final QueryEngine queryEngine = QueryEngineFactory + .getQueryController(jnl); + + // still exists and is the same reference. + assertTrue(queryEngine == QueryEngineFactory + .getExistingQueryController(jnl)); + + ncreated++; + + } + + } catch (OutOfMemoryError err) { + + log.error("Out of memory after creating " + ncreated + + " query controllers."); + } - } catch (OutOfMemoryError err) { - - log.error("Out of memory after creating " + ncreated - + " query controllers."); + // Demand a GC. + System.gc(); - } + // Wait for it. + Thread.sleep(1000/* ms */); - // Demand a GC. - System.gc(); + if (log.isInfoEnabled()) + log.info("Created " + ncreated + " query controllers."); - // Wait for it. - Thread.sleep(1000/*ms*/); - - if(log.isInfoEnabled()) - log.info("Created " + ncreated + " query controllers."); + final int nalive = QueryEngineFactory.getQueryControllerCount(); - final int nalive = QueryEngineFactory.getQueryControllerCount(); + if (log.isInfoEnabled()) + log.info("There are " + nalive + + " query controllers which are still alive."); - if (log.isInfoEnabled()) - log.info("There are " + nalive - + " query controllers which are still alive."); + if (nalive == ncreated) { - if (nalive == ncreated) { + fail("No query controllers were finalized."); - fail("No query controllers were finalized."); + } + } finally { + + /* + * Ensure that all journals are destroyed by the end of the test. + */ + for (int i = 0; i < refs.length; i++) { + final Journal jnl = refs[i] == null ? null : refs[i].get(); + if (jnl != null) { + jnl.destroy(); + } + } + } } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestJournalShutdown.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestJournalShutdown.java 2011-05-31 10:46:52 UTC (rev 4576) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestJournalShutdown.java 2011-05-31 12:25:32 UTC (rev 4577) @@ -27,6 +27,7 @@ package com.bigdata.journal; +import java.lang.ref.WeakReference; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; @@ -84,7 +85,7 @@ public void test_memoryLeakWithoutExplicitClose() throws InterruptedException { -// // This test currently fails.... +// // This test currently fails.... [this has been fixed]. // fail("See https://sourceforge.net/apps/trac/bigdata/ticket/196."); doMemoryLeakTest(false); @@ -125,83 +126,112 @@ final AtomicInteger ncreated = new AtomicInteger(); final AtomicInteger nunfinalized = new AtomicInteger(); + /* + * An array of weak references to the journals. These references will + * not cause the journals to be retained. However, since we can not + * force a major GC, the non-cleared references are used to ensure that + * all journals are destroyed by the end of this test. + */ + final WeakReference<Journal>[] refs = new WeakReference[limit]; + try { + try { - for (int i = 0; i < limit; i++) { + for (int i = 0; i < limit; i++) { - final Journal jnl = new Journal(properties) { - protected void finalize() throws Throwable { - super.finalize(); - nunfinalized.decrementAndGet(); - if (log.isDebugEnabled()) - log.debug("Journal was finalized: ncreated=" - + ncreated + ", nalive=" + nunfinalized); - } - }; + final Journal jnl = new Journal(properties) { + protected void finalize() throws Throwable { + super.finalize(); + nunfinalized.decrementAndGet(); + if (log.isDebugEnabled()) + log + .debug("Journal was finalized: ncreated=" + + ncreated + + ", nalive=" + + nunfinalized); + } + }; - nunfinalized.incrementAndGet(); - ncreated.incrementAndGet(); + refs[i] = new WeakReference<Journal>(jnl); - if (closeJournal) { - /* - * Exercise each of the ways in which we can close the - * journal. - * - * Note: The Journal will not be finalized() unless it is - * closed. It runs a variety of services which have - * references back to the Journal and which will keep it - * from being finalized until those services are shutdown. - */ - switch (i % 4) { - case 0: - jnl.shutdown(); - break; - case 1: - jnl.shutdownNow(); - break; - case 2: - jnl.close(); - break; - case 3: - jnl.destroy(); - break; - default: - throw new AssertionError(); + nunfinalized.incrementAndGet(); + ncreated.incrementAndGet(); + + if (closeJournal) { + /* + * Exercise each of the ways in which we can close the + * journal. + * + * Note: The Journal will not be finalized() unless it + * is closed. It runs a variety of services which have + * references back to the Journal and which will keep it + * from being finalized until those services are + * shutdown. + */ + switch (i % 4) { + case 0: + jnl.shutdown(); + break; + case 1: + jnl.shutdownNow(); + break; + case 2: + jnl.close(); + break; + case 3: + jnl.destroy(); + break; + default: + throw new AssertionError(); + } + } } + } catch (OutOfMemoryError err) { + + log.error("Out of memory after creating " + ncreated + + " journals."); + } - } catch (OutOfMemoryError err) { + // Demand a GC. + System.gc(); - log.error("Out of memory after creating " + ncreated - + " journals."); + // Wait for it. + Thread.sleep(1000/* ms */); - } + if (log.isInfoEnabled()) { - // Demand a GC. - System.gc(); + log.info("Created " + ncreated + " journals."); - // Wait for it. - Thread.sleep(1000/* ms */); + log.info("There are " + nunfinalized + + " journals which are still alive."); - if (log.isInfoEnabled()) { + } - log.info("Created " + ncreated + " journals."); + if (nunfinalized.get() == ncreated.get()) { - log.info("There are " + nunfinalized - + " journals which are still alive."); + fail("Created " + ncreated + + " journals. No journals were finalized."); - } + } - if (nunfinalized.get() == ncreated.get()) { + } finally { - fail("Created " + ncreated - + " journals. No journals were finalized."); + /* + * Ensure that all journals are destroyed by the end of the test. + */ + for (int i = 0; i < refs.length; i++) { + final Journal jnl = refs[i] == null ? null : refs[i].get(); + if (jnl != null) { + jnl.destroy(); + } + } } - + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |