Java - GUI clock using large amounts of RAM?

2019-01-09 17:03发布

I made a little clock for a desktop widget in Java(the widget includes many other features as well). I checked the applications RAM usage in task manager to see that the clock was using 700+ MB of RAM. I disabled the clock and the RAM usage went down to about 60 MB. Here is the clocks code:

final int timeRun = 0;
    new Thread()
    {
        public void run()
        {
            while(timeRun == 0)
            {
                Calendar cal = new GregorianCalendar();
                int hour = cal.get(Calendar.HOUR);
                int min = cal.get(Calendar.MINUTE);
                int sec = cal.get(Calendar.SECOND);
                int AM_PM = cal.get(Calendar.AM_PM);

                String day_night = "";

                if (AM_PM == 1){
                    day_night = "PM";
                }else{
                    day_night = "AM";
                }

                String time = hour + ":" + min + ":" + sec + " " + day_night;
                Clock.setText(time);
            }
        }
    }.start();

Why is it using so much RAM? How could I fix it?

标签: java timer
1条回答
在下西门庆
2楼-- · 2019-01-09 17:27
  1. Reduce the number of updates to the required minimum
  2. Reduce the number of temporary objects as best as you can
  3. Ensure that all updates to the UI are made from within the context of the main UI thread (Event Dispatching Thread for Swing)

Take a look at:

For example...

Clock

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ClockMeBaby {

    public static void main(String[] args) {
        new ClockMeBaby();
    }

    public ClockMeBaby() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {

        protected static final DateFormat CLOCK_FORMAT = new SimpleDateFormat("hh:mm:ss a");
        private JLabel clock;

        public TestPane() {
            setLayout(new GridBagLayout());
            clock = new JLabel("...");
            clock.setFont(clock.getFont().deriveFont(Font.BOLD, 64f));
            add(clock);
            updateClock();

            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    updateClock();
                }
            });
            timer.start();
        }

        protected void updateClock() {

            clock.setText(CLOCK_FORMAT.format(System.currentTimeMillis()));

        }

    }

}

The reason the SwingTimer uses a 500 millisecond delay is to ensure we remain in sync, otherwise your clock might update "out of sync" with the rest of the UI because you've missed a second boundry. If this is not important to you, you could us 1000 millisecond delay instead

查看更多
登录 后发表回答