diff -r e04777e1d582 java.kit/test/qa-functional/src/org/netbeans/test/ide/MemoryValidationTest.java --- a/java.kit/test/qa-functional/src/org/netbeans/test/ide/MemoryValidationTest.java Mon Aug 31 12:25:23 2009 +0200 +++ b/java.kit/test/qa-functional/src/org/netbeans/test/ide/MemoryValidationTest.java Mon Aug 31 17:22:56 2009 +0200 @@ -100,7 +100,7 @@ conf = conf.addTest("testGCDocuments"); -// conf = conf.addTest("testGCProjects"); + conf = conf.addTest("testGCProjects"); // not in commit suite because it needs net connectivity // suite.addTest(new IDEValidation("testPlugins")); return NbModuleSuite.create(conf); diff -r e04777e1d582 parsing.api/src/org/netbeans/modules/parsing/api/Source.java --- a/parsing.api/src/org/netbeans/modules/parsing/api/Source.java Mon Aug 31 12:25:23 2009 +0200 +++ b/parsing.api/src/org/netbeans/modules/parsing/api/Source.java Mon Aug 31 17:22:56 2009 +0200 @@ -424,7 +424,7 @@ private final ASourceModificationEvent unspecifiedSourceModificationEvent = new ASourceModificationEvent (this, -1, -1); private Map,? extends SchedulerEvent> schedulerEvents; //GuardedBy(this) - private SourceCache cache; + private Reference cache; //GuardedBy(this) private volatile long eventId; //Changes handling @@ -627,9 +627,12 @@ public SourceCache getCache (final Source source) { assert source != null; synchronized (TaskProcessor.INTERNAL_LOCK) { - if (source.cache == null) - source.cache = new SourceCache (source, null); - return source.cache; + SourceCache sc = source.cache != null ? source.cache.get() : null; + if (sc == null) { + sc = new SourceCache (source, null); + source.cache = new WeakReference(sc); + } + return sc; } } diff -r e04777e1d582 parsing.api/src/org/netbeans/modules/parsing/impl/CurrentDocumentScheduler.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/CurrentDocumentScheduler.java Mon Aug 31 12:25:23 2009 +0200 +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/CurrentDocumentScheduler.java Mon Aug 31 17:22:56 2009 +0200 @@ -39,6 +39,8 @@ package org.netbeans.modules.parsing.impl; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import javax.swing.text.Document; import javax.swing.text.JTextComponent; @@ -55,17 +57,17 @@ */ @ServiceProvider(service=Scheduler.class) public class CurrentDocumentScheduler extends CurrentEditorTaskScheduler { - private Document currentDocument; - private Source source; + private Reference source; protected void setEditor (JTextComponent editor) { if (editor != null) { Document document = editor.getDocument (); if (currentDocument == document) return; currentDocument = document; - source = Source.create (currentDocument); - schedule (source, new SchedulerEvent (this) {}); + Source s = Source.create (currentDocument); + source = new WeakReference(s); + schedule (s, new SchedulerEvent (this) {}); } else { currentDocument = null; @@ -78,7 +80,7 @@ * @param source */ void schedule (Source source) { - this.source = source; + this.source = new WeakReference(source); schedule (source, new SchedulerEvent (this) {}); } @@ -89,7 +91,8 @@ @Override protected SchedulerEvent createSchedulerEvent (SourceModificationEvent event) { - if (event.getModifiedSource () == source) + Source s = source == null ? null : source.get(); + if (event.getModifiedSource () == s) return new SchedulerEvent (this) {}; return null; } diff -r e04777e1d582 parsing.api/src/org/netbeans/modules/parsing/impl/CursorSensitiveScheduler.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/CursorSensitiveScheduler.java Mon Aug 31 12:25:23 2009 +0200 +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/CursorSensitiveScheduler.java Mon Aug 31 17:22:56 2009 +0200 @@ -39,6 +39,8 @@ package org.netbeans.modules.parsing.impl; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.Document; @@ -62,7 +64,7 @@ private JTextComponent currentEditor; private CaretListener caretListener; private Document currentDocument; - private Source source; + private Reference source; protected void setEditor (JTextComponent editor) { @@ -76,8 +78,9 @@ Document document = editor.getDocument (); if (currentDocument == document) return; currentDocument = document; - source = Source.create (currentDocument); - schedule (source, new CursorMovedSchedulerEvent (this, editor.getCaret ().getDot (), editor.getCaret ().getMark ()) {}); + Source s = Source.create (currentDocument); + source = new WeakReference(s); + schedule (s, new CursorMovedSchedulerEvent (this, editor.getCaret ().getDot (), editor.getCaret ().getMark ()) {}); } else { currentDocument = null; @@ -92,7 +95,8 @@ @Override protected SchedulerEvent createSchedulerEvent (SourceModificationEvent event) { - if (event.getModifiedSource () == source) + Source s = source == null ? null : source.get(); + if (event.getModifiedSource () == s) return new CursorMovedSchedulerEvent (this, currentEditor.getCaret ().getDot (), currentEditor.getCaret ().getMark ()) {}; return null; } diff -r e04777e1d582 parsing.api/src/org/netbeans/modules/parsing/impl/SelectedNodesScheduler.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/SelectedNodesScheduler.java Mon Aug 31 12:25:23 2009 +0200 +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/SelectedNodesScheduler.java Mon Aug 31 17:22:56 2009 +0200 @@ -42,6 +42,8 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import org.netbeans.modules.parsing.spi.SchedulerEvent; import org.netbeans.modules.parsing.spi.SourceModificationEvent; import org.openide.filesystems.FileObject; @@ -63,7 +65,7 @@ public class SelectedNodesScheduler extends Scheduler { - private Source source; + private Reference source; public SelectedNodesScheduler () { TopComponent.getRegistry ().addPropertyChangeListener (new AListener ()); @@ -81,10 +83,13 @@ final DataObject dataObject = nodes [0].getLookup ().lookup (DataObject.class); if (dataObject != null && dataObject.isValid()) { final FileObject fileObject = dataObject.getPrimaryFile (); - if (fileObject.isValid() && Util.canBeParsed(fileObject.getMIMEType())) - source = Source.create (fileObject); - if (source != null) { - schedule (source, new SchedulerEvent (this) {}); + Source s = null; + if (fileObject.isValid() && Util.canBeParsed(fileObject.getMIMEType())) { + s = Source.create (fileObject); + source = new WeakReference(s); + } + if (s != null) { + schedule (s, new SchedulerEvent (this) {}); return; } } @@ -100,7 +105,8 @@ @Override protected SchedulerEvent createSchedulerEvent (SourceModificationEvent event) { - if (event.getModifiedSource () == source) + Source s = source == null ? null : source.get(); + if (event.getModifiedSource () == s) return new SchedulerEvent (this) {}; return null; } diff -r e04777e1d582 parsing.api/src/org/netbeans/modules/parsing/spi/Scheduler.java --- a/parsing.api/src/org/netbeans/modules/parsing/spi/Scheduler.java Mon Aug 31 12:25:23 2009 +0200 +++ b/parsing.api/src/org/netbeans/modules/parsing/spi/Scheduler.java Mon Aug 31 17:22:56 2009 +0200 @@ -39,6 +39,8 @@ package org.netbeans.modules.parsing.spi; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; @@ -79,7 +81,7 @@ */ int reparseDelay = DEFAULT_REPARSE_DELAY; - private Source source; + private Reference source; /** * This implementations of {@link Scheduler} reschedules all tasks when: @@ -116,8 +118,11 @@ protected final void schedule ( SchedulerEvent event ) { - if (source != null) - schedule (source, event); + Reference obj = source; + Source s = obj == null ? null : obj.get(); + if (s != null) { + schedule(s, event); + } } private RequestProcessor @@ -141,24 +146,38 @@ if (task != null) task.cancel (); task = null; - this.source = source; + this.source = new WeakReference(source); //if (task == null) { if (requestProcessor == null) requestProcessor = new RequestProcessor (); - task = requestProcessor.create (new Runnable () { - public void run () { - SourceCache cache = SourceAccessor.getINSTANCE ().getCache (source); - Map,SchedulerEvent> events = new HashMap,SchedulerEvent> (); - events.put (Scheduler.this.getClass (), event); - SourceAccessor.getINSTANCE ().setSchedulerEvents (source, events); - //S ystem.out.println ("\nSchedule tasks (" + Scheduler.this + "):"); - cache.scheduleTasks (Scheduler.this.getClass ()); - } - }); + task = requestProcessor.create (new Run(this, source, event)); //} task.schedule (reparseDelay); } + private static final class Run implements Runnable { + private final Scheduler scheduler; + private SchedulerEvent event; + private Source source; + + private Run(Scheduler aThis, Source source, SchedulerEvent ev) { + this.scheduler = aThis; + this.source = source; + this.event = ev; + } + + + public void run() { + SourceCache cache = SourceAccessor.getINSTANCE().getCache(source); + Map, SchedulerEvent> events = new HashMap, SchedulerEvent>(); + events.put(scheduler.getClass(), event); + SourceAccessor.getINSTANCE().setSchedulerEvents(source, events); + //S ystem.out.println ("\nSchedule tasks (" + Scheduler.this + "):"); + cache.scheduleTasks(scheduler.getClass()); + source = null; + } + } + protected abstract SchedulerEvent createSchedulerEvent (SourceModificationEvent event); private static boolean notNull (final Iterable it) {