-
22. 01. 2012, 18:04 #1Mitglied
- Registriert seit
- Aug 2007
- Beiträge
- 7
[Java] Speicherproblem mit repaint()
Hi,
da ich dieses Jahr Abitur schreiben, hab ich mir mal einen kleinen Countdown geschrieben, der mich daran erinnert zu lernen.. Jetzt ist mir aber aufgefallen, dass wohl die repaint()-Funktion einen Speicherüberlauf auslöst, mit dem Resultat, dass die java.exe mit jedem Aufruf (also ca. alle 0,5sec) 10-20k an Arbeitsspeicher mehr belegt. Da der Countdown natürlich am besten dauerhaft laufen sollte, ist das nicht so gut.
Hat jemand eine Idee, wie man das fixen könnte?
Btw: Ich benutze Java 7. Vllt liegts daran?
Vielen Dank schonmal!Code:import javax.swing.*; import java.awt.*; import java.util.Calendar; import java.util.Date; public class CountDown extends JWindow implements Runnable { //End-Date of Countdowns private Date d2=new Date(2012,3,20); //blink private boolean b=true; private Image dbImage; public CountDown() { this.setSize(200,50); this.setLocation((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth()/2-getWidth()/2), (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()-getHeight()); this.setAlwaysOnTop(true); this.setVisible(true); Thread th=new Thread(this); th.start(); } //Attribute: End-Date public CountDown(Date d2) { this.setSize(200,50); this.setLocation((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth()/2-getWidth()/2), (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()-getHeight()); this.setAlwaysOnTop(true); Thread th=new Thread(this); this.d2=d2; th.start(); } public void paint(Graphics g) { super.paint(g); //Aktuelle Zeit Date d=new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(d); if(cal.get(Calendar.MONTH)==0)cal.set(Calendar.MONTH,1); d=cal.getTime(); //Countdown Date d3=new Date(d2.getTime()-d.getTime()); Calendar cal3 = Calendar.getInstance(); cal3.setTime(d3); if(cal3.get(Calendar.MINUTE)==0&&b) { g.setColor(Color.RED); b=false; }else b=true; //Draw shit g.fillRect(0,0,this.getWidth(),this.getHeight()); g.setColor(Color.RED); g.setFont(new Font("OCR A Extended",Font.BOLD,20)); g.drawString("t -"+cal3.get(Calendar.DAY_OF_YEAR)+" "+cal3.get(Calendar.HOUR_OF_DAY)+":"+cal3.get(Calendar.MINUTE)+":"+cal3.get(Calendar.SECOND),10,30); } public static void main(String argv[]) { new CountDown(); } public void update (Graphics g) { Graphics dbg=null; // Initialisierung des DoubleBuffers if (dbImage == null) { dbImage = createImage (this.getSize().width, this.getSize().height); dbg = dbImage.getGraphics (); } // Bggcildschirm im Hintergrund l�schen dbg.setColor (getBackground ()); dbg.fillRect (0, 0, this.getSize().width, this.getSize().height); // Auf gel�schten Hintergrund Vordergrund zeichnen dbg.setColor (getForeground()); paint(dbg); // Nun fertig gezeichnetes Bild Offscreen auf dem richtigen Bildschirm anzeigen g.drawImage (dbImage, 0, 0, this); } public void run() { while(true) { if(!this.isVisible())this.setVisible(true); this.repaint(); try { Thread.sleep(500); } catch (Exception e) { } } } }
MfG
Lukas
-
26. 01. 2012, 01:46 #2Mitglied
- Registriert seit
- Nov 2007
- Beiträge
- 272
Re: [Java] Speicherproblem mit repaint()
Bin da mal drüber gegangen und habe den Code ein wenig bereinigt, bitte Kommentare beachten

Bei mir nutzt der auch immer mehr Speicher allerdings kann es ein, dass die JVM irgendwann damit aufhört, dh. du solltest es einmal ein paar Stunden laufen lassen und gucken ob es ein Maximum gibt, oder ob es crasht.
Es gab mal nen Speicherbug mit dauernden repaint() aufrufen, der aber seit langem gefixt sein sollte (der hat euch ruckzuck die VM weggeschossen).
Die update Methode ist komplett nutzlos und wird nie aufgerufen, also weg damitPHP-Code:import javax.swing.*;
import java.awt.*;
import java.util.Calendar;
import java.util.Date;
public class CountDown extends JWindow implements Runnable {
// End-Date of Countdowns
private Date d2 = new Date(2012, 3, 20);
// blink
private boolean b = true;
// so gibt es keine magic numbers
private final int xSize = 200, ySize = 50;
public CountDown() {
this.setSize(xSize, ySize);
this.setLocation((int) (Toolkit.getDefaultToolkit().getScreenSize()
.getWidth() / 2 - xSize / 2), (int) Toolkit
.getDefaultToolkit().getScreenSize().getHeight()
- ySize);
this.setAlwaysOnTop(true);
this.setVisible(true);
}
// Attribute: End-Date
public CountDown(Date d2) {
this.d2 = d2;
this.setSize(xSize, ySize);
this.setLocation((int) (Toolkit.getDefaultToolkit().getScreenSize()
.getWidth() / 2 - getWidth() / 2), (int) Toolkit
.getDefaultToolkit().getScreenSize().getHeight()
- getHeight());
this.setAlwaysOnTop(true);
}
public void paint(Graphics g) {
// super.paint(g);
// Aktuelle Zeit
Date d = new Date();
Calendar cal = Calendar.getInstance();
// calendar instanzen haben bereits die zeit also wech hiermit
// cal.setTime(d);
// warum magst du keinen januar?
if (cal.get(Calendar.MONTH) == 0)
cal.set(Calendar.MONTH, 1);
d = cal.getTime();
// recycle cal & date!
// Countdown
d.setTime(d2.getTime() - d.getTime());
// brauchen wir nicht nimm einfach den alten
// das vermeidet auch komische Variablennamen
// Calendar cal3 = Calendar.getInstance();
cal.setTime(d);
// immer wenn 10 minuten voll sind hast du rote schrift auf rotem grund...
if (cal.get(Calendar.MINUTE) == 0 && b) {
g.setColor(Color.RED);
b = false;
} else
b = true;
g.setFont(new Font("OCR A Extended", Font.BOLD, 20));
// Draw shit
g.fillRect(0, 0, xSize, ySize);
g.setColor(Color.RED);
g.drawString(
"t -" + cal.get(Calendar.DAY_OF_YEAR) + " "
+ cal.get(Calendar.HOUR_OF_DAY) + ":"
+ cal.get(Calendar.MINUTE) + ":"
+ cal.get(Calendar.SECOND), 10, 30);
}
public static void main(String argv[]) {
CountDown bla = new CountDown();
new Thread(bla).start();
}
public void run() {
while (true) {
// always ob top erledigt das sowieso
//if (!this.isVisible())
// this.setVisible(true);
this.repaint();
try {
// du zählst in sekunden also lasse den thread auch so laufen ;)
Thread.sleep(1000);
} catch (Exception e) {
}
}
}

-
26. 01. 2012, 10:51 #3Mitglied
(Threadstarter)
- Registriert seit
- Aug 2007
- Beiträge
- 7
Re: [Java] Speicherproblem mit repaint()
Danke für die Anmerkungen
Der Countdown blinkt alle 60 Minuten (immer wenn die Minuten auf 0 sind) und nicht alle 10. Desswegen wird der Thread auch alle 0.5sec refresht damit das blinken nicht so langsam (,penetranter) ist.
Die update Methode wird von JComponents überschrieben (http://docs.oracle.com/javase/7/docs...wt.Graphics%29) und soll für den Doppelpufferung sorgen (bei einem kollegen hats beim refresh "geruckelt", daher...)
MfG
Lukas
-


Zitieren
mehr lesen...







Resident Evil 6 erscheint in...
Heute, 15:21 in gulli:news