// StatusMemory - display the memory status of the Java virtual machine // // Copyright (C)1996,1998 by Jef Poskanzer . All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. import java.applet.*; import java.awt.*; import java.lang.*; import java.util.*; public class StatusMemory extends Applet implements Runnable { // Applet info. public String getAppletInfo() { return getClass().getName() + " - Copyright (C) 1996 by Jef Poskanzer . All rights reserved."; } // Called when the applet is first created. public void init() { Acme.GuiUtils.handleBgcolor( this ); } private Thread thread = null; // Called when the applet should start itself. public void start() { if ( thread == null ) { // Start the thread. thread = new Thread(this); thread.start(); } } // Called when the applet should stop itself. public void stop() { if ( thread != null ) { // Stop the thread. thread.stop(); thread = null; } } // This is the part of Runnable that we implement - the routine that // gets called when the thread is started. public void run() { Thread me = Thread.currentThread(); me.setPriority( Thread.MIN_PRIORITY ); while ( thread == me ) { repaint(); try { Thread.sleep( 2000 ); } catch ( InterruptedException e ) {} } } // The default update() clears the background and then calls paint(). // This one doesn't clear the background. public void update( Graphics graphics ) { paint( graphics ); } private Runtime runtime = Runtime.getRuntime(); private Image offsc = null; private Dimension offscSize = null; private Graphics offscGraphics = null; private int pppUsageK = Integer.MAX_VALUE; private int ppUsageK = Integer.MAX_VALUE; private int pUsageK = Integer.MAX_VALUE; private long pppTime = new Date().getTime(); private long ppTime = new Date().getTime(); private long pTime = new Date().getTime(); private float pppKPerSec = 0.0F; private float ppKPerSec = 0.0F; private float pKPerSec = 0.0F; private float usageKPerSec = Float.MAX_VALUE; private int pHardK = Integer.MAX_VALUE; private int hardK = Integer.MAX_VALUE; private long pHardTime = new Date().getTime(); private float hardKPerMin = Float.MAX_VALUE; // Called when the applet should paint itself. public void paint( Graphics graphics ) { int pad = 5; Dimension size = size(); // Dimension size = getSize(); FontMetrics fm = graphics.getFontMetrics(); int lineHeight = ( size.height - pad ) / 3; int barHeight = lineHeight * 2 / 3; long total = runtime.totalMemory(); int totalK = (int) ( ( total + 1023 ) / 1024 ); long free = runtime.freeMemory(); int usageK = (int) ( ( total - free + 1023 ) / 1024 ); long time = new Date().getTime(); if ( pUsageK != Integer.MAX_VALUE && usageK < pUsageK ) { pHardK = hardK; hardK = usageK; if ( pHardK != Integer.MAX_VALUE && time != pHardTime ) hardKPerMin = (float) ( hardK - pHardK ) * 60.0F * 1000.0F / (float) ( time - pHardTime ); } if ( pppUsageK != Integer.MAX_VALUE && ppUsageK >= pppUsageK && ppTime != pppTime ) pppKPerSec = (float) ( ppUsageK - pppUsageK ) * 1000.0F / (float) ( ppTime - pppTime ); if ( ppUsageK != Integer.MAX_VALUE && pUsageK >= ppUsageK && pTime != ppTime ) ppKPerSec = (float) ( pUsageK - ppUsageK ) * 1000.0F / (float) ( pTime - ppTime ); if ( pUsageK != Integer.MAX_VALUE && usageK >= pUsageK && time != pTime ) pKPerSec = (float) ( usageK - pUsageK ) * 1000.0F / (float) ( time - pTime ); // Make weighted average. if ( pppKPerSec != Float.MAX_VALUE && ppKPerSec != Float.MAX_VALUE && pKPerSec != Float.MAX_VALUE ) usageKPerSec = ( 3.0F * pKPerSec + 2.0F * ppKPerSec + 1.0F * pppKPerSec ) / 6.0F; String totalKStr = Integer.toString( totalK ); String usageKStr = Integer.toString( usageK ); String hardKStr = Integer.toString( hardK ); int totalKStrWid = fm.stringWidth( totalKStr ); int usageKStrWid = fm.stringWidth( usageKStr ); int hardKStrWid = fm.stringWidth( hardKStr ); int totalBarWid = size.width - pad - totalKStrWid - pad; int usageBarWid = totalBarWid * usageK / totalK; int hardBarWid = totalBarWid * hardK / totalK; // Rotate old values. pppUsageK = ppUsageK; ppUsageK = pUsageK; pUsageK = usageK; pppTime = ppTime; ppTime = pTime; pTime = time; // Get off-screen graphics buffer if necessary. if ( offsc == null || offscSize.width != size.width || offscSize.height != size.height ) { offsc = createImage( size.width, size.height ); offscSize = size; offscGraphics = offsc.getGraphics(); } // Draw into off-screen buffer. offscGraphics.setColor( getBackground() ); offscGraphics.fillRect( 0, 0, size.width, size.height ); offscGraphics.setColor( Color.green ); offscGraphics.drawString( totalKStr, size.width - pad - totalKStrWid, lineHeight ); if ( hardK != Integer.MAX_VALUE ) { offscGraphics.setColor( Color.red ); offscGraphics.drawString( hardKStr, hardBarWid - hardKStrWid - pad, 2 * lineHeight ); } offscGraphics.setColor( Color.yellow ); offscGraphics.drawString( usageKStr, usageBarWid, 2 * lineHeight ); int hardStrWid = 0; if ( hardKPerMin != Float.MAX_VALUE ) { String hardStr = "hard: " + Acme.Fmt.fmt( hardKPerMin, 0, 3 ) + " KB/min"; offscGraphics.setColor( Color.red ); offscGraphics.drawString( hardStr, 0, 3 * lineHeight ); hardStrWid = fm.stringWidth( hardStr ) + pad * 5; } if ( usageKPerSec != Float.MAX_VALUE ) { String usageStr = "usage: " + Acme.Fmt.fmt( usageKPerSec, 0, 3 ) + " KB/sec"; offscGraphics.setColor( Color.yellow ); offscGraphics.drawString( usageStr, hardStrWid, 3 * lineHeight ); } offscGraphics.setColor( Color.green ); offscGraphics.fillRect( 0, lineHeight - barHeight, totalBarWid, barHeight ); offscGraphics.setColor( Color.yellow ); offscGraphics.fillRect( 0, lineHeight - barHeight, usageBarWid, barHeight ); if ( hardK != Integer.MAX_VALUE ) { offscGraphics.setColor( Color.red ); offscGraphics.fillRect( 0, lineHeight - barHeight, hardBarWid, barHeight ); } // Copy onto screen. graphics.drawImage( offsc, 0, 0, this ); } // Main program, so we can run as an application too. public static void main( String[] args ) { new Acme.MainFrame( new StatusMemory(), args, 250, 50 ); } }