Ergebnis 1 bis 3 von 3
  1. #1
    Mitglied
    Registriert seit
    Aug 2007
    Beiträge
    7

    Standard [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?

    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) {
                }
            }
        }
    }
    Vielen Dank schonmal!
    MfG

    Lukas

  2. #2
    Mitglied
    Registriert seit
    Nov 2007
    Beiträge
    272

    Standard 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).

    PHP-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(2012320);
        
    // blink
        
    private boolean b true;
        
        
    // so gibt es keine magic numbers
        
    private  final int xSize 200,  ySize 50

        public 
    CountDown() {
            
    this.setSize(xSizeySize);
            
    this.setLocation((int) (Toolkit.getDefaultToolkit().getScreenSize()
                    .
    getWidth() / 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(xSizeySize);
            
    this.setLocation((int) (Toolkit.getDefaultToolkit().getScreenSize()
                    .
    getWidth() / 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.MONTH1);
            
    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) == && b) {
                
    g.setColor(Color.RED);
                
    false;
            } else
                
    true;

            
    g.setFont(new Font("OCR A Extended"Font.BOLD20));
            
            
    // Draw shit
            
    g.fillRect(00xSizeySize);

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

        }

        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) {
                }
            }
        } 
    Die update Methode ist komplett nutzlos und wird nie aufgerufen, also weg damit

  3. #3
    Mitglied

    (Threadstarter)


    Registriert seit
    Aug 2007
    Beiträge
    7

    Standard 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

  4.  
     
     

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •