Ich stieß auf das Problem der Speicherverlust in Swing-Anwendung aufgrund Swing Timer.Swing Timer ist kein Müll gesammelt
Ich habe Timer verwendet, um Diashow von Bildern in Page1 anzuzeigen.
Als ich die Anwendung profilierte, bemerkte ich, dass beim Navigieren zu dem Timer-Objekt das Page1-Objekt und jedes Objekt in Page1-Objekt nicht Garbage Collected war.
Ich kam zu wissen, stopping der Timer ermöglicht es, Müll gesammelt werden.
Ich ging davon aus, dass wenn ein Objekt nicht referenziert wird, es für die Garbage Collection bereit ist. Aber diese Annahme ist in diesem Fall gescheitert.
Der folgende Code fasst meine Anwendung zusammen und hat keinen Speicherverlust. Um Speicherleck zu sehen, kommentieren Sie die Zeile, in der ich stopTimer
Methode von Timer
aufgerufen habe.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class TimerMemoryLeak {
public static void main(String[] args) {
TimerMemoryLeak timer = new TimerMemoryLeak();
timer.buildUI();
}
public void buildUI() {
showPanel1();
frame.setSize(600, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void showPanel1() {
Page1 page1 = new Page1();
if (currentPanel != null) {
pane.remove(((Page2) currentPanel).getPanel());
}
pane.add(page1.getPanel());
currentPanel = page1;
page1.startTimer();
page1.setNextAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showPanel2();
}
});
pane.revalidate();
pane.repaint();
}
public void showPanel2() {
Page2 page2 = new Page2();
if (currentPanel != null) {
((Page1) currentPanel).stopTimer(); // Comment this for memory leak
pane.remove(((Page1) currentPanel).getPanel());
}
pane.add(page2.getPanel());
currentPanel = page2;
page2.setPreviousAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showPanel1();
}
});
pane.revalidate();
pane.repaint();
}
private JFrame frame = new JFrame();
private Container pane = frame.getContentPane();
private Object currentPanel;
}
class Page1 {
public Page1() {
panel.add(title, BorderLayout.NORTH);
panel.add(textTimer);
panel.add(btnNext, BorderLayout.SOUTH);
}
public void setNextAction(ActionListener listener) {
btnNext.addActionListener(listener);
}
public JPanel getPanel() {
return panel;
}
public void startTimer() {
timer.setInitialDelay(0);
timer.start();
}
public void stopTimer() {
timer.stop();
}
private JPanel panel = new JPanel(new BorderLayout());
private JLabel title = new JLabel("Panel 1");
private JButton btnNext = new JButton("Next");
private JLabel textTimer = new JLabel();
private int timerInterval = 1000;
private ActionListener timerAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
textTimer.setText(Math.random() + "");
}
};
private Timer timer = new Timer(timerInterval, timerAction);
}
class Page2 {
public Page2() {
panel.add(title, BorderLayout.NORTH);
panel.add(btnPrev, BorderLayout.SOUTH);
}
public void setPreviousAction(ActionListener listener) {
btnPrev.addActionListener(listener);
}
public JPanel getPanel() {
return panel;
}
private JPanel panel = new JPanel(new BorderLayout());
private JLabel title = new JLabel("Panel 2");
private JButton btnPrev = new JButton("Previous");
}
Was könnte der mögliche Grund dafür sein?
* "Ich habe dieses Problem der Speicherverlust .." * Die einzige Möglichkeit, sicher sein, einen Speicherverlust zu sein, ist ein ' OutOfMEmoryError'. Funktioniert die App? einen werfen? Es ist bekannt, dass der Müllsammler ziemlich konservativ ist bezüglich dessen, was er sammelt, und oft handelt er nur dann, wenn er es für nötig hält. –
Ich konnte kein Leck erkennen, wie hier [hier] (https://stackoverflow.com/a/45124503/230513). – trashgod
@AndrewThompson Während der Profilerstellung in Netbeans können Sie Live-Objekte zählen. "OutOfMemoryError" ist nicht die einzige Möglichkeit, den Speicherleck zu bestätigen, obwohl dies letztendlich auftreten wird. Außerdem habe ich zur Erklärung des Codes meine Frage hinzugefügt. – Barun