Утечка памяти при использовании setText - PullRequest
4 голосов
/ 11 декабря 2011

Я заметил, что в моей программе есть утечка памяти.

Я отследил проблему до линии.

Clock.setText("" + h + ":" + df.format(m) + ":" + df.format(s));

Я гуглил это, и, похоже, это общая проблема, но я не нашел ответа.

Кто-нибудь знает исправление?

Вот весь код:

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();

    }
}

Ответы [ 2 ]

6 голосов
/ 11 декабря 2011

Ваша программа выглядит нормально для меня. Обратите внимание, как периодический сборщик мусора возвращается к исходному уровню. В отличие от этого пример утечки ресурсов хоста. Самое большее, вы можете использовать StringBuilder или MessageFormat в вашем setText() вызове.

enter image description here

2 голосов
/ 11 декабря 2011

Вот вывод слегка измененной версии кода.

14145904
13602336
13059104
12515968
12063384
15263600
14758304
14253408
13748576
13197160
12646360
12057192
11552120
15472056
14960064
14448336
13875144
13363416
12851488
12309120
11681480
15661104
15142224
14602560
14063128
13523464
12983832
12444168
11904536
11364648
15325136
14770848
14230296
13690032
..

Я не вижу здесь утечки памяти.

Измененный код

import java.awt.*;
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.*;

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);

        ActionListener memoryListener = new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                System.out.println(Runtime.getRuntime().freeMemory());
            }
        };
        Timer memTimer = new Timer(1000,memoryListener);
        memTimer.start();

        // 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(10, refreshListener);
        refreshTimer.setInitialDelay(0);
        refreshTimer.start();

    }
}
...