//----------------------------------------------------------------------------// // // // M e m o r y M e t e r // // // //----------------------------------------------------------------------------// // <editor-fold defaultstate="collapsed" desc="hdr"> // // Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. // // This software is released under the GNU General Public License. // // Goto http://kenai.com/projects/audiveris to report bugs or suggestions. // //----------------------------------------------------------------------------// // </editor-fold> package omr.ui; import omr.constant.Constant; import omr.constant.ConstantSet; import omr.ui.util.UIUtil; import omr.util.Memory; import org.jdesktop.application.Action; import org.jdesktop.application.ApplicationContext; import org.jdesktop.application.ResourceMap; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; /** * Class {@code MemoryMeter} encapsulates the display of a linear memory * meter in MB (both used and total), together with a garbage-collection * button. * * <P>There is a alarm threshold that triggers a color switch to red whenever * the used memory exceeds the threshold. * * @author Hervé Bitteur */ public class MemoryMeter { //~ Static fields/initializers --------------------------------------------- /** Specific application parameters */ private static final Constants constants = new Constants(); /** A mega as 2**20 */ private static final double MEGA = 1024 * 1024; //~ Instance fields -------------------------------------------------------- /** Default foreground color, when under alarm threshold */ private Color defaultForeground; /** Related concrete component */ private JPanel component; /** Progress bar */ private JProgressBar progressBar = new JProgressBar(); /** Runnable that displays the memory usage */ private Runnable displayer; /** Flag on monitoring activity */ private volatile boolean monitoring; /** Last value for global memory, in order to save on display */ private int lastTotal = 0; /** Last value for used memory, in order to save on display */ private int lastUsed = 0; /** Last value for threshold, in order to save on display */ private int lastThreshold = 0; //~ Constructors ----------------------------------------------------------- //-------------// // MemoryMeter // //-------------// /** * Basic Memory Meter, with default alarm threshold and display period. */ public MemoryMeter () { component = new JPanel(); try { defineUI(); initialize(); } catch (Exception ex) { ex.printStackTrace(); } } //~ Methods ---------------------------------------------------------------- //----------------// // collectGarbage // //----------------// @Action public void collectGarbage () { System.gc(); System.runFinalization(); System.gc(); displayMemory(); } //---------------// // displayMemory // //---------------// /** * Trigger an immediate memory display */ public void displayMemory () { SwingUtilities.invokeLater(displayer); } //--------------// // getComponent // //--------------// /** * Report the UI component * * @return the concrete component */ public JComponent getComponent () { return component; } //------// // stop // //------// /** * Stop the memory monitoring */ public void stop () { monitoring = false; } //----------// // defineUI // //----------// private void defineUI () { ApplicationContext applicationContext = MainGui.getInstance() .getContext(); component.setLayout(new BorderLayout()); // Progress bar progressBar.setPreferredSize(new Dimension(90, 20)); progressBar.setName("progressBar"); progressBar.setToolTipText("Used memory / Global memory"); progressBar.setStringPainted(true); component.add(progressBar, BorderLayout.CENTER); // Garbage collector button JButton button = new JButton( applicationContext.getActionMap(this).get("collectGarbage")); button.setBorder(UIUtil.getToolBorder()); component.add(button, BorderLayout.EAST); // Remember the default foreground color defaultForeground = progressBar.getForeground(); // Resource injection ResourceMap resource = applicationContext.getResourceMap(getClass()); resource.injectComponents(component); } //------------// // initialize // //------------// private void initialize () { // Displayer displayer = new Runnable() { @Override public void run () { int total = (int) Math.rint(Memory.total() / MEGA); int used = (int) Math.rint(Memory.occupied() / MEGA); int threshold = (int) Math.rint( constants.alarmThreshold.getValue() * total); if ((total != lastTotal) || (used != lastUsed) || (threshold != lastThreshold)) { progressBar.setMaximum(total); progressBar.setValue(used); progressBar.setString( String.format("%d/%d MB", used, total)); lastTotal = total; lastUsed = used; lastThreshold = threshold; if (used > threshold) { progressBar.setForeground(Color.red); } else { progressBar.setForeground(defaultForeground); } } } }; // Monitoring thread Thread monitorThread = new Thread() { @Override public void run () { monitoring = true; while (monitoring) { displayMemory(); try { sleep(constants.displayPeriod.getValue()); } catch (InterruptedException ex1) { monitoring = false; } } } }; monitorThread.setName(getClass().getName()); monitorThread.setPriority(Thread.MIN_PRIORITY); monitorThread.start(); } //~ Inner Classes ---------------------------------------------------------- //-----------// // Constants // //-----------// private static final class Constants extends ConstantSet { //~ Instance fields ---------------------------------------------------- /** Display period */ Constant.Integer displayPeriod = new Constant.Integer( "MilliSeconds", 2000, "Memory display period"); /** Alarm threshold ratio */ Constant.Ratio alarmThreshold = new Constant.Ratio( 0.75, "Memory alarm threshold, expressed in ratio of total memory"); } }