Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
al072
15 / 15 / 4
Регистрация: 03.02.2010
Сообщений: 133
1

Out of Memory Exception в программе для Windows Mobile

09.04.2014, 07:15. Просмотров 1197. Ответов 6
Метки нет (Все метки)

Добрый день, уважаемые форумчане! Давно не обращался за помощью, но пришлось) Написал приложение для платформы Windows Mobile, которое на стадии проверки правильных ответов, в runtime в отдельной форме динамически создает порядка 20-ти PictureBox и TextBox. К каждому PictureBox привязывается картинка, которая создается методом выделения памяти следующим образом:
C#
1
2
3
4
5
6
7
8
9
private void ShowAnswer()
{
PictureBox = new PictureBox();
PictureBox.BackColor = Color.Red;
PictureBox.Location = new Point(x,y);
PictureBox.Name = "Name";
PictureBox.Size = Size(w,h);
PictureBox.Image = new Bitmap(\\Image01.jpg);
}
Дак вот проблема в том что крайне редко, если работать с программой около часа, при очередном вызове функции проверки результата вылетает ошибка Out of Memory Exception.. я так полагаю что где-то есть Memory leaks, но не могу разобраться где именно.. После каждого вызова функции правильных ответов, которая создает отдельную форму и динамически создает в нем PictureBox И TextBox элементы, при закрытии формы в событии Form closing, я в ручную вызываю метод Dispose() и сборщик мусора GC.Collect() для всех созданных элементов:
C#
1
2
3
4
5
foreach(Control cntrl in this.Controls)
{
    cntrl.Dispose();
    GC.Collect();
}
Но проблема всеравно остается.. я предполагаю что память либо утекает, либо в определенный момент не успевает освобождаться при очередном вызове функции правильных ответов.

Просьба подскажите может существуют более правильные способы выделения памяти для большого количества динамически создаваемых картинок? Или я не правильно вызываю Dispose() ? или может есть какие либо способы кеширования Bitmap и его последующего освобождения? спасибо всем за советы... жду вашей помощи коллеги!
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.04.2014, 07:15
Ответы с готовыми решениями:

Unhandled exception at 0x7c812a5b : Microsoft C++ exception: std::bad_alloc at memory location 0x0012f350
что то я запутался совсем. подскажите где глюк? Считываю из XML данные: char*...

Unhandled exception at at 0x75E717D2 in ConsoleApplication24.exe: Microsoft C++ exception: std::out_of_range at memory l
Здравствуйте, помогите пожалуйста, при проходе через последний цикл выдаёт вот такую ошибку:...

Выдаёт ошибку "Unhandled exception at 0x00007F exception: std::bad_alloc in memory location"
Добрый день, друзья не могли бы помочь разобраться, почему выдаёт такую ошибку? Вот #include...

Exception class EOutOfMemory with message 'Out of memory'
Подскажите, в чем проблема? void __fastcall TForm1::Button1Click(TObject *Sender) { float x, y,...

Не работает флешка Sansung Flash Memory - Mobile Storage 8gb
Всем привет. Суть моей проблемы вот в чем: в универе извлекли флешку из компа без безопасного...

6
Learx
1048 / 855 / 194
Регистрация: 31.03.2010
Сообщений: 2,506
09.04.2014, 17:33 2
1) у меня такое подозрение, что вы создаете гораздо больше контролов.
попробуйте в вашем методе ShowAnswer не создавать контрол, а обращаться к тому, который существует уже
2) перед загрузкой новой картинки удаляйте старую, приблизительно так:
C#
1
2
3
4
5
//получаем картинку, которая отображалась ранее
Bitmap old = PictureBox.Image as Bitmap;
//проверяем действительно ли была картинка
if(old!=null) 
   old.Dispose(); //уничтожаем картинку
0
al072
15 / 15 / 4
Регистрация: 03.02.2010
Сообщений: 133
10.04.2014, 06:22  [ТС] 3
1) у меня такое подозрение, что вы создаете гораздо больше контролов.
попробуйте в вашем методе ShowAnswer не создавать контрол, а обращаться к тому, который существует уже
2) перед загрузкой новой картинки удаляйте старую, приблизительно так:
------------------------------------------------------------------------------------------
1) Я наверное не совсем корректно описал свой метод, дело в том что каждый новый контрол создается со своим именем и местоположением в цикле, и устанавливать картинку на контрол который уже существует я не могу, мне необходимо загружать битмап для каждого вновь создаваемого PictureBox:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
     
     for (int i =0;i=20;i++)
     {
          private void ShowAnswer(int x,int y, string Name,int w,int h)
       {
          PictureBox = new PictureBox();
          PictureBox.BackColor = Color.Red;
          PictureBox.Location = new Point(x,y);
          PictureBox.Name = Name;
          PictureBox.Size = Size(w,h);
          PictureBox.Image = new Bitmap("\\Image01+i.ToString()");
         } 
      }
2) Я пробовол вызывать метод PictureBox.Image.Dispose() после каждой итерации цикла, чтобы картинка сперва была присвоена PictureBox, а затем ее ресурсы были освобождены, но в этом случаее при загрузке новой формы в которой динамически создаются эти контролы - я получаю Disposed object exception, что не удивительно, так как на форме не может быть отрисован уже уничтоженный элемент..
3) Я пробовал проходится в цикле по динамически созданным контролам и освобождать память выделенную под Bitmap уже после того, как все контролы созданы:

C#
1
2
3
4
5
6
7
foreach (Control cntrl in this.Controls)
{
     if (cntrl is PictureBox)
     {
         ((PictureBox)cntrl).Image.Dispose();
     }
}
Но это не помогает избавиться от Out of Memory exception, так как переполнение происходит именно в момент выделения памяти под каждый новый Bitmap. Вот если бы можно было каким либо образом в цикле, в котором создаются контролы с каждой итерацией сперва выделять память под Bitmap и в этой же итерации освобождать ее, то думаю OOM бы не возникало, но тогда вопрос в том как избавиться от Disposed object exception - ведь на форме не могут быть отрисованы уже высвобожденные из памяти Bitmapы.
0
Learx
1048 / 855 / 194
Регистрация: 31.03.2010
Сообщений: 2,506
10.04.2014, 14:01 4
al072,
дайте полностью проект. выдернутый кусок не дает должного представление о логике вашей программы.
0
al072
15 / 15 / 4
Регистрация: 03.02.2010
Сообщений: 133
12.04.2014, 13:44  [ТС] 5
Цитата Сообщение от Learx Посмотреть сообщение
al072,
дайте полностью проект. выдернутый кусок не дает должного представление о логике вашей программы.
К сожалению не могу дать исходники - проект коммерческий.

Логика простая. Пользователь решает 20 задач, когда нажимает кнопку проверить результат, вызывается метод ShowAnswer(), вот полный код метода:

C#
1
2
3
4
5
6
7
8
9
   private void ShowAnswer(int x,int y, string Name,int w,int h)
       {
          PictureBox = new PictureBox();
          PictureBox.BackColor = Color.Red;
          PictureBox.Location = new Point(x,y);
          PictureBox.Name = Name;
          PictureBox.Size = Size(w,h);
          PictureBox.Image = new Bitmap("\\Image01+i.ToString()");
         }
Вот так вызывается метод:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void ShowAnswerButton_Click(object sender, EventArgs e)
{
     picturebox_location_x = 3;
     picturebox_location_y = 37;
     picturebox_size_w = 220;
     picturebox_size_h = 75;
 
 
     for (int i =0;i=20;i++)
     { 
          ShowAnswer(picturebox_location_x,picturebox_location_y, i.ToString(),picturebox_size_w,picturebox_size_h);
          picturebox_location_x += 275;
          picturebox_location_y += 275;
 
     }
 
}
И все эти пикчербоксы в цикле рисуются на дочерней форме, но спустя некоторое время, если интенсивно работать с программой и часто вызывать метод ShowAnswer() - происходит OOM. Пожалуйста дайте знать, если требуется какая-либо дополнительная информация.. спасибо..
0
Learx
1048 / 855 / 194
Регистрация: 31.03.2010
Сообщений: 2,506
14.04.2014, 17:51 6
al072, как я уже говорил, должно быть совершенно иначе:
1) создаем форму или UserControl где и должны быть наши PictureBox с ответами. пусть даже они создаются динамически в конструкторе:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
List<PictureBox> picList = new List<PictureBox>();//поле класса
//конструктор
{
  picturebox_location_x = 3;
     picturebox_location_y = 37;
     picturebox_size_w = 220;
     picturebox_size_h = 75;
 
 
     for (int i =0;i=20;i++)
     { 
         picList.Add(CreateBox(picturebox_location_x,picturebox_location_y, i.ToString(),picturebox_size_w,picturebox_size_h));
          picturebox_location_x += 275;
          picturebox_location_y += 275;
 
     } 
}
 
private PictureBox CreateBox(int x,int y, string Name,int w,int h)
       {
          PictureBox pb = new PictureBox();
          pb.BackColor = Color.Red;
          pb.Location = new Point(x,y);
          pb.Name = Name;
          pb.Size = Size(w,h);
          return pb;
         }
2. Создадим метод, который корректно будет обновлять картинку в каждом PictureBox по списку имен файлов-изображений
C#
1
2
3
4
5
6
7
8
public void UpdateImage(List<string> fnames)
{ 
     if(fnames.Count!=picList.Cout) throw new ArgumentExeption();
     for(int i=0; i<picList.Count; i++)
     {  
           pb.Load(fnames[i]);
     } 
}
3. формируем список файлов и вызываем UpdateImage для нашего контрола, или формы или чего там...

Добавлено через 6 минут
как-то так:
C#
1
2
3
4
5
6
7
8
9
private void ShowAnswerButton_Click(object sender, EventArgs e)
{
 List<string> fnames = new List<string>();
 for(int i=0; i<20; i++)
 {
      fnames.Add("\\Image"+i.ToString());
 }
 this.UpdateImage(frames);
}
0
al072
15 / 15 / 4
Регистрация: 03.02.2010
Сообщений: 133
14.04.2014, 18:33  [ТС] 7
Большое спасибо за развернутый ответ, но как ваш способ поможет избавиться от ООМ? Чем он отличается в плане распределения памяти при загрузке картинок от моего? PictureBox в Net CF 3.5 не имеет метода Load(); как вы указали, по-этому указать просто текстовый путь к файлу не получиться.. Картинки то всеравно придется грузить при помощи new Bitmap.. Или я что-то не так понимаю?
0
14.04.2014, 18:33
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.04.2014, 18:33

Делаю Memory Manager Array с простым (int) exception последний элемент чудит
//array_hpp #ifndef Array_HPP #define Array_HPP #include &quot;Point.hpp&quot; #include &lt;iostream&gt; ...

Ошибка при написании класса: Unhandled exception std::bad_alloc at memory location
ПИшу свой клас Var, проблема в следующем из-за строчки first = first+1; вылетает ошибка ...

C# для Windows Mobile
Кто кодит под WM? Как развернуть свёрнутое приложение повторным нажатием на exe файл? пытался...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.