I have noticed that I have a memory leak in my program.
I have traced the problem to the line.
Clock.setText("" + h + ":" + df.format(m) + ":" + df.format(s));
I have googled this and it seems to be a common problem but I have not found an answer.
Does anyone know a fix?
Here is the entire code:
package CodeBits;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class Countdown {
private JFrame Timer;
private JTextField Clock;
private JLabel label;
private JLabel label_1;
static Calendar calendar = new GregorianCalendar();
int minutes = 90;
int count = minutes * 60;
int h;
int m;
int s;
javax.swing.Timer refreshTimer;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Countdown window = new Countdown();
window.Timer.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Countdown() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
Timer = new JFrame();
Timer.getContentPane().setBackground(new Color(173, 216, 230));
Timer.setBounds(0, 0, 135, 100);
Timer.setTitle("Aero Software");
Timer.setIconImage(Toolkit.getDefaultToolkit().getImage("Files/Icon.jpg"));
Timer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0, 0};
gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
gridBagLayout.columnWeights = new double[]{0.0, 0.0, 1.0, 1.0, 0.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
Timer.getContentPane().setLayout(gridBagLayout);
label = new JLabel(" ");
GridBagConstraints gbc_label = new GridBagConstraints();
gbc_label.insets = new Insets(0, 0, 5, 5);
gbc_label.gridx = 0;
gbc_label.gridy = 1;
Timer.getContentPane().add(label, gbc_label);
JLabel lblNewLabel = new JLabel("Countdown Timer");
GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
gbc_lblNewLabel.gridwidth = 4;
gbc_lblNewLabel.insets = new Insets(0, 0, 5, 0);
gbc_lblNewLabel.gridx = 1;
gbc_lblNewLabel.gridy = 1;
Timer.getContentPane().add(lblNewLabel, gbc_lblNewLabel);
Clock = new JTextField();
Clock.setFont(new Font("Arial", Font.BOLD, 22));
Clock.setHorizontalAlignment(JLabel.CENTER);
GridBagConstraints gbc_Clock = new GridBagConstraints();
gbc_Clock.fill = GridBagConstraints.HORIZONTAL;
gbc_Clock.gridwidth = 3;
gbc_Clock.insets = new Insets(0, 0, 5, 5);
gbc_Clock.gridx = 1;
gbc_Clock.gridy = 2;
Timer.getContentPane().add(Clock, gbc_Clock);
Clock.setColumns(10);
label_1 = new JLabel(" ");
GridBagConstraints gbc_label_1 = new GridBagConstraints();
gbc_label_1.insets = new Insets(0, 0, 5, 0);
gbc_label_1.gridx = 4;
gbc_label_1.gridy = 2;
Timer.getContentPane().add(label_1, gbc_label_1);
// Create countdown timer
ActionListener refreshListener = new ActionListener() {
// Ensure time is fotmatted as 7:04 not 7:4
DecimalFormat df = new DecimalFormat("00");
Calendar countdown = calendar;
{
// Zero the time and add the number of minutes to countdown from
countdown.set(Calendar.HOUR, 0);
countdown.set(Calendar.MINUTE, 0);
countdown.set(Calendar.SECOND, 0);
countdown.set(Calendar.MINUTE, 0);
countdown.add(Calendar.MINUTE, minutes);
}
// Start the timer
public void actionPerformed(ActionEvent e) {
h = countdown.get(Calendar.HOUR_OF_DAY);
m = countdown.get(Calendar.MINUTE);
s = countdown.get(Calendar.SECOND);
calendar.add(Calendar.SECOND, -1);
Clock.setText("" + h + ":" + df.format(m) + ":" + df.format(s));
count--;
if (count == 0) {
System.out.println("Time is up!");
refreshTimer.stop();
}
}
};
refreshTimer = new javax.swing.Timer(1000, refreshListener);
refreshTimer.setInitialDelay(0);
refreshTimer.start();
}
}
Your program looks OK to me. Note how periodic GC returns to baseline. In contrast, this example leaks host resources. At most, you might consider using
StringBuilder
orMessageFormat
in yoursetText()
invocation.Here is the output of a slightly altered version of the code.
I see no memory leak here.
Altered code