package vtk; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.swing.SwingUtilities; /** * This class helps to provide a solution in concurrent garbage collection issue * with VTK. This class allow automatic garbage collection done in a specific * thread such as the EDT. * * @author sebastien jourdain - sebastien.jourdain@kitware.com */ public class vtkJavaGarbageCollector { private ScheduledExecutorService executor; private Runnable deleteRunnable; private Runnable deferredEdtRunnable; private long periodTime; private TimeUnit timeUnit; private boolean autoCollectionRunning; private boolean debug; /** * Build a garbage collector which is configured to garbage collect every * seconds but has not been started yet. The user has to call * SetAutoGarbageCollection(true) to make it start. */ public vtkJavaGarbageCollector() { // Default settings debug = false; periodTime = 1; timeUnit = TimeUnit.SECONDS; autoCollectionRunning = false; // executor = Executors.newSingleThreadScheduledExecutor(); deleteRunnable = new Runnable() { public void run() { // Do the delete here vtkReferenceInformation info = vtkObjectBase.JAVA_OBJECT_MANAGER.gc(debug); if (debug) { System.out.println(info); System.out.println(info.listKeptReferenceToString()); System.out.println(info.listRemovedReferenceToString()); } } }; deferredEdtRunnable = new Runnable() { public void run() { SwingUtilities.invokeLater(deleteRunnable); } }; } /** * Set the schedule time that should be used to send a garbage collection * request to the EDT. * * @param period * @param timeUnit */ public void SetScheduleTime(long period, TimeUnit timeUnit) { this.periodTime = period; this.timeUnit = timeUnit; SetAutoGarbageCollection(autoCollectionRunning); } /** * Whether to print out when garbage collection is run. * * @param debug */ public void SetDebug(boolean debug) { this.debug = debug; } /** * Start or stop the automatic garbage collection in the EDT. * * @param doGarbageCollectionInEDT */ public void SetAutoGarbageCollection(boolean doGarbageCollectionInEDT) { autoCollectionRunning = doGarbageCollectionInEDT; executor.shutdown(); if (doGarbageCollectionInEDT) { executor = Executors.newSingleThreadScheduledExecutor(); executor.scheduleAtFixedRate(deferredEdtRunnable, periodTime, periodTime, timeUnit); } } /** * Shortcut for SetAutoGarbageCollection(true) * @see SetAutoGarbageCollection */ public void Start() { this.SetAutoGarbageCollection(true); } /** * Shortcut for SetAutoGarbageCollection(false) * @see SetAutoGarbageCollection */ public void Stop() { this.SetAutoGarbageCollection(false); } /** * @return the runnable that do the garbage collection. This could be used * if you want to execute the garbage collection in another thread * than the EDT. */ public Runnable GetDeleteRunnable() { return deleteRunnable; } }