package ij.plugin.frame; import ij.*; import ij.gui.*; import ij.process.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; /** This plugin continuously plots ImageJ's memory utilization. Click on the plot to force the JVM to do garbage collection. */ public class MemoryMonitor extends PlugInFrame { private static final int WIDTH=250, HEIGHT=90; private static final String LOC_KEY = "memory.loc"; private static MemoryMonitor instance; private Image image; private Graphics2D g; private int frames; private double[] mem; private int index; private long value; private double defaultMax = 15*1204*1024; // 15MB private double max = defaultMax; private long maxMemory = IJ.maxMemory(); public MemoryMonitor() { super("Memory"); if (instance!=null) { WindowManager.toFront(instance); return; } instance = this; WindowManager.addWindow(this); setLayout(new BorderLayout()); Canvas ic = new Canvas(); ic.setSize(WIDTH, HEIGHT); add(ic); setResizable(false); pack(); Point loc = Prefs.getLocation(LOC_KEY); if (loc!=null) setLocation(loc); else GUI.center(this); image = createImage(WIDTH,HEIGHT); g = (Graphics2D)image.getGraphics(); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g.setColor(Color.white); g.fillRect(0, 0, WIDTH, HEIGHT); g.setFont(new Font("SansSerif",Font.PLAIN,12)); Graphics icg = ic.getGraphics(); icg.drawImage(image, 0, 0, null); show(); ImageJ ij = IJ.getInstance(); if (ij!=null) { addKeyListener(ij); ic.addKeyListener(ij); ic.addMouseListener(ij); } mem = new double[WIDTH+1]; Thread.currentThread().setPriority(Thread.MIN_PRIORITY); while (true) { updatePlot(); addText(); icg.drawImage(image, 0, 0, null); IJ.wait(50); frames++; } } void addText() { double value2 = (double)value/1048576L; String s = IJ.d2s(value2,value2>50?0:2)+"MB"; if (maxMemory>0L) { double percent = value*100/maxMemory; s += " ("+(percent<1.0?"<1":IJ.d2s(percent,0)) + "%)"; } g.drawString(s, 2, 15); String images = ""+WindowManager.getImageCount(); g.drawString(images, WIDTH-(5+images.length()*8), 15); } void updatePlot() { double used = IJ.currentMemory(); if (frames%10==0) value = (long)used; if (used>0.86*max) max *= 2.0; mem[index++] = used; if (index==mem.length) index = 0; double maxmax = 0.0; for (int i=0; i<mem.length; i++) { if (mem[i]>maxmax) maxmax= mem[i]; } if (maxmax<defaultMax) max=defaultMax*2; if (maxmax<defaultMax/2) max = defaultMax; int index2 = index+1; if (index2==mem.length) index2 = 0; g.setColor(Color.white); g.fillRect(0, 0, WIDTH, HEIGHT); g.setColor(Color.black); double scale = HEIGHT/max; int x1 = 0; int y1 = HEIGHT-(int)(mem[index2]*scale); for (int x2=1; x2<WIDTH; x2++) { index2++; if (index2==mem.length) index2 = 0; int y2 = HEIGHT-(int)(mem[index2]*scale); g.drawLine(x1, y1, x2, y2); x1=x2; y1=y2; } } public void close() { super.close(); instance = null; Prefs.saveLocation(LOC_KEY, getLocation()); } }