Утечка памяти в часах C #

#c# #memory #clock

#c# #память #часы

Вопрос:

У меня утечка памяти в этом проекте C #. Это аналоговые часы, и использование памяти увеличивается с каждой секундой. Какая ошибка была скрыта?

         private void timer1_Tick(object sender, EventArgs e)
        {
            DateTime Now = DateTime.Now;
            int Hour = Now.Hour;
            int Minute = Now.Minute;
            int Second = Now.Second;

            Single AngleS = Second * 6;
            Single AngleM = Minute * 6   AngleS / 60;
            Single AngleH = Hour * 30   AngleM / 12;

            backBox.Image = back;
            backBox.Controls.Remove(backBox);
            backBox.Controls.Add(hourBox);

            hourBox.Location = new Point(0, 0);
            hourBox.Image = rotateImage(hour, AngleH);
            hourBox.Controls.Add(minuteBox);

            minuteBox.Location = new Point(0, 0);
            minuteBox.Image = rotateImage(minute, AngleM);
            minuteBox.Controls.Add(dotBox);
            
            dotBox.Location = new Point(0, 0);
            dotBox.Image = dot;
            dotBox.Controls.Add(secondBox);
            
            secondBox.Location = new Point(0, 0);
            secondBox.Image = rotateImage(second, AngleS);
        }


 

Комментарии:

1. Вы продолжаете добавлять Controls . Это, вероятно, бесполезно и потребляет память.

2. Покажите нам код для метода rotateImage().

Ответ №1:

System.Drawing.Image объекты — это IDisposable s, поэтому вам нужно позаботиться Dispose() о любых повернутых изображениях, которые вы больше не используете.

В зависимости от вашего макета (который мы не видим из вашего фрагмента), может быть хорошей идеей провести рефакторинг, чтобы вы когда-либо рисовали повернутые объекты на одном изображении.

Ответ №2:

 private void timer1_Tick(object sender, EventArgs e)
    {
        DateTime Now = DateTime.Now;
        int Hour = Now.Hour;
        int Minute = Now.Minute;
        int Second = Now.Second;

        Single AngleS = Second * 6;
        Single AngleM = Minute * 6   AngleS / 60;
        Single AngleH = Hour * 30   AngleM / 12;

        // add this code
        // i think
        // backBox.Image.Dispose() is better but that can cause other errors
        backBox.Image = null;
        //
        backBox.Image = back;
        backBox.Controls.Remove(backBox);
        backBox.Controls.Add(hourBox);

        hourBox.Location = new Point(0, 0);
        
        //add this code
        hourBox.Image = null;
        //
        hourBox.Image = rotateImage(hour, AngleH);
        hourBox.Controls.Add(minuteBox);

        minuteBox.Location = new Point(0, 0);
        // add this code
        minuteBox.Image = null;
        //
        minuteBox.Image = rotateImage(minute, AngleM);
        minuteBox.Controls.Add(dotBox);
        
        dotBox.Location = new Point(0, 0);
        // add this code
        dotBox.Image = null;
        //
        dotBox.Image = dot;
        dotBox.Controls.Add(secondBox);
        
        secondBox.Location = new Point(0, 0);
        // add this code
        secondBox.Image = null;
        //
        secondBox.Image = rotateImage(second, AngleS);
    }
 

Есть одна часть, которая меня беспокоит

 private Bitmap rotateImage(Bitmap rotateMe, float angle)        
{             
    Bitmap rotatedImage = new Bitmap(rotateMe.Width, rotateMe.Height);   

    using (Graphics g = Graphics.FromImage(rotatedImage))  
    {                 
        g.TranslateTransform(rotateMe.Width / 2, rotateMe.Height / 2);          
        g.RotateTransform(angle);                 
        g.TranslateTransform(-rotateMe.Width / 2, -rotateMe.Height / 2);     
        g.DrawImage(rotateMe, new Point(0, 0));                             
    }
                   
    return rotatedImage;       
}
 

minuteBox.Image = rotageedImage = rotateMe = минута

итак, если вы введете значение null, это может привести к сбою. Имейте это в виду!

Ответ №3:

Старый образ должен быть удален, поэтому

     hourBox.Image = rotateImage(hour, AngleH);      
 

Изменить на

     var OldImage = hourBox.Image;
    hourBox.Image = rotateImage(hour, AngleH);
    if(OldImage != null )
    {
        OldImage.Dispose();
    }
 

Проделайте то же самое с minute, dot и second .