X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fgui%2FFreeUpMemoryTest.java;h=e93bfac7162c27177ffb25d1c8e0a438d550c9d7;hb=918faab51fdcb2ff14958e5ca46ba75b73d17991;hp=2a9a8c9f79ff4cdb7b1c73b50083d0ca8f7c6886;hpb=b1acf8c1977aafaaed3117a1ea89cf06b08b716b;p=jalview.git diff --git a/test/jalview/gui/FreeUpMemoryTest.java b/test/jalview/gui/FreeUpMemoryTest.java index 2a9a8c9..e93bfac 100644 --- a/test/jalview/gui/FreeUpMemoryTest.java +++ b/test/jalview/gui/FreeUpMemoryTest.java @@ -1,10 +1,13 @@ package jalview.gui; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import jalview.analysis.AlignmentGenerator; import jalview.bin.Cache; import jalview.bin.Jalview; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceGroup; import jalview.io.DataSourceType; import jalview.io.FileLoader; @@ -17,7 +20,7 @@ import org.testng.annotations.Test; public class FreeUpMemoryTest { - private static final int ONE_MB = 1024 * 1024; + private static final int ONE_MB = 1000 * 1000; /** * Configure (read-only) Jalview property settings for test @@ -50,12 +53,12 @@ public class FreeUpMemoryTest * * * If the test fails, this suggests that a reference to some large object - * (perhaps the alignment data, or consensus profile) has failed to be garbage - * collected. If this is the case, the heap will need to be inspected manually - * (suggest using jvisualvm) in order to track down where large objects are - * still referenced. The code (for example AlignmentViewport.dispose()) should - * then be updated to ensure references to large objects are set to null when - * they are no longer required. + * (perhaps the alignment data, or some annotation / Tree / PCA data) has + * failed to be garbage collected. If this is the case, the heap will need to + * be inspected manually (suggest using jvisualvm) in order to track down + * where large objects are still referenced. The code (for example + * AlignmentViewport.dispose()) should then be updated to ensure references to + * large objects are set to null when they are no longer required. * * @throws IOException */ @@ -65,29 +68,34 @@ public class FreeUpMemoryTest File f = generateAlignment(); f.deleteOnExit(); + doStuffInJalview(f); + + Desktop.instance.closeAll_actionPerformed(null); + + checkUsedMemory(35L); + } + + /** + * Requests garbage collection and then checks whether remaining memory in use + * is less than the expected value (in Megabytes) + * + * @param expectedMax + */ + protected void checkUsedMemory(long expectedMax) + { /* - * load alignment, wait for consensus and other threads to complete + * request garbage collection and wait briefly for it to run; + * NB there is no guarantee when, or whether, it will do so */ - AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(f.getPath(), - DataSourceType.FILE); - waitForThreads(af.getViewport()); - - af.closeMenuItem_actionPerformed(true); + System.gc(); + waitFor(100); /* - * request garbage collection and allow 1 second for it to complete; - * NB there is no guarantee when, or whether, it will run! + * a second gc() call should not be necessary - but it is! + * the test passes with it, and fails without it */ System.gc(); - synchronized (this) - { - try - { - wait(1000); - } catch (InterruptedException e) - { - } - } + waitFor(100); /* * check used memory is 'reasonably low' @@ -95,8 +103,12 @@ public class FreeUpMemoryTest long availableMemory = Runtime.getRuntime().totalMemory() / ONE_MB; long freeMemory = Runtime.getRuntime().freeMemory() / ONE_MB; long usedMemory = availableMemory - freeMemory; - System.out.println("Memory in use after close all windows: " - + usedMemory + "MB"); + + /* + * sanity check - fails if any frame was added after + * closeAll_actionPerformed + */ + assertEquals(Desktop.instance.getAllFrames().length, 0); /* * if this assertion fails @@ -105,32 +117,88 @@ public class FreeUpMemoryTest * - identify large objects in the heap and their referers * - fix code as necessary to null the references on close */ - long expectedMax = 100L; - assertTrue(usedMemory < expectedMax, - String.format("Used memory %d > %d", usedMemory, expectedMax)); + System.out.println("Used memory after gc = " + usedMemory + "MB"); + assertTrue(usedMemory < expectedMax, String.format( + "Used memory %d should be less than %d (Recommend running test manually to verify)", + usedMemory, + expectedMax)); + } + + /** + * Loads an alignment from file and exercises various operations in Jalview + * + * @param f + */ + protected void doStuffInJalview(File f) + { + /* + * load alignment, wait for consensus and other threads to complete + */ + AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(f.getPath(), + DataSourceType.FILE); + while (af.getViewport().isCalcInProgress()) + { + waitFor(200); + } + + /* + * set a selection group - potential memory leak if it retains + * a reference to the alignment + */ + SequenceGroup sg = new SequenceGroup(); + sg.setStartRes(0); + sg.setEndRes(100); + AlignmentI al = af.viewport.getAlignment(); + for (int i = 0; i < al.getHeight(); i++) + { + sg.addSequence(al.getSequenceAt(i), false); + } + af.viewport.setSelectionGroup(sg); + + /* + * compute Tree and PCA (on all sequences, 100 columns) + */ + af.openTreePcaDialog(); + CalculationChooser dialog = af.alignPanel.getCalculationDialog(); + dialog.openPcaPanel("BLOSUM62", dialog.getSimilarityParameters(true)); + dialog.openTreePanel("BLOSUM62", dialog.getSimilarityParameters(false)); + + /* + * wait until Tree and PCA have been computed + */ + while (af.viewport.getCurrentTree() == null + && dialog.getPcaPanel().isWorking()) + { + waitFor(10); + } + + /* + * give Swing time to add the PCA panel (?!?) + */ + waitFor(100); } /** - * wait for consensus etc thread to complete + * Wait for waitMs miliseconds * - * @param av + * @param waitMs */ - protected void waitForThreads(AlignViewport av) + protected void waitFor(int waitMs) { - while (av.isCalcInProgress()) + try + { + Thread.sleep(waitMs); + } catch (InterruptedException e) { - try - { - Thread.sleep(200); - } catch (Exception x) - { - } } } /** - * Generates an alignment (large enough for this test but not so large it is - * too slow or runs out of memory) and saves it in a temporary file. + * Generates an alignment and saves it in a temporary file, to be loaded by + * Jalview. We use a peptide alignment (so Conservation and Quality are + * calculated), which is wide enough to ensure Consensus, Conservation and + * Occupancy have a significant memory footprint (if not removed from the + * heap). * * @return * @throws IOException @@ -140,7 +208,9 @@ public class FreeUpMemoryTest File f = File.createTempFile("MemoryTest", "fa"); PrintStream ps = new PrintStream(f); AlignmentGenerator ag = new AlignmentGenerator(false, ps); - ag.generate(1000, 20000, 0, 10, 15); + int width = 100000; + int height = 100; + ag.generate(width, height, 0, 10, 15); return f; } }