Проблема Out Of Memory

Интерфейс, диалоги, темы, стили, меню
Ответить
Артем Дегтев
Сообщения: 74
Зарегистрирован: 27 янв 2014, 00:05

Проблема Out Of Memory

Сообщение Артем Дегтев » 31 янв 2014, 18:13

Нашел место в котором вылетает программа, выдает Out Of Memory.
Весь класс:

Код: Выделить всё

public class BDInListView extends Thread {
		String[] NewsAfterDate;

		BDInListView(String newsAfterDate) {
			NewsAfterDate = new String[] { newsAfterDate };
		}

		public void run() {
			ClassForBD DBClass = new ClassForBD(MainActivity.this);
			SQLiteDatabase BD = DBClass.getWritableDatabase();
			Cursor c = BD.query("NewsRadio24", null, "UpdateDate<?",
					NewsAfterDate, null, null, "UpdateDate DESC");
			Drawable  smallImage= null;
			try {
				if (c.moveToFirst()) {
					int idColIndex = c.getColumnIndex("ID_In_Site");
					int nameColIndex = c.getColumnIndex("Name");
					int annotationColIndex = c.getColumnIndex("Annotation");
					int summaryColIndex = c.getColumnIndex("Summary");
					int updateDateColIndex = c.getColumnIndex("UpdateDate");
					int SmallImagePathColIndex = c
							.getColumnIndex("SmallImagePath");
					int NormalImagePathColIndex = c
							.getColumnIndex("NormalImagePath");
					int SmallImageColIndex = c.getColumnIndex("SmallImage");
					int NormalImageColIndex = c.getColumnIndex("NormalImage");
					do {
						int id_news = c.getInt(idColIndex);
						String name_news = c.getString(nameColIndex);
						String annotation_news = c
								.getString(annotationColIndex);
						String summary_news = c.getString(summaryColIndex);
						String updateDate_news = MilisecToDate(c
								.getString(updateDateColIndex));
						String imgnormalPath = c
								.getString(NormalImagePathColIndex);
						String imgsmallPath = c
								.getString(SmallImagePathColIndex);
						byte[] smallImageBlob = c.getBlob(SmallImageColIndex);
						byte[] normalImageBlob = c.getBlob(NormalImageColIndex);
						  smallImage = BlobToDrawable(smallImageBlob);
						SearchResultItem item = new SearchResultItem(id_news,
								smallImage, name_news, updateDate_news,
								summary_news, annotation_news, null);
						smallImage=null;
						Message msg = handle.obtainMessage(1, item);
						handle.sendMessage(msg);
					} while (c.moveToNext());

				} else
					Log.d("End read", "0 rows");
			} finally {
				c.close();

			}
			
			Message m = EndAddingInListvew.obtainMessage(1, ")");
			EndAddingInListvew.sendMessage(m);
			
		}
	}
Хандлер handle:

Код: Выделить всё

		handle = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				adapter.add((SearchResultItem) msg.obj);
				adapter.notifyDataSetChanged();
				msg.obj = null;
 			}
		};
		
Проблемное место в классе:

Код: Выделить всё

SearchResultItem item = new SearchResultItem(id_news,
								smallImage, name_news, updateDate_news,
								summary_news, annotation_news, null);
Если вместо smallImage отправлять нул или любую картинку из ресурсов, то отлично работает, если отправлять smallImage то вылетает через определенное количество раз вызова класса.
То есть, если просто убрать smallImage и вставить null то все отлично работает, то есть проблема не в функции BlobToDrawable().

Что тут может быть?

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Проблема Out Of Memory

Сообщение anber » 31 янв 2014, 18:40

Собственно корень проблемы: smallImage это Drawable, а Drawable содержит внутри себя Bitmap.
Предположим Bitmap имеет размер 5 мегапикселей (типично разрешение для фотки с камеры), имеет размер = 2500х2000 пикселей, каждый пиксель весит 4 байта (aRGB), т.е. фотка размером 5 мегапикселей в оперативке займет 19 мегабайт.
Далее: на 1 процесс в андроиде выделяется в среднем 64 мегабайта, та что путем нехитрых математических операций получим что в память влезет 3 - 5 картинок большого размера.

Отсюда 2 вывода, как избавиться от OOME:
1) не хранить много ссылок на большие картинки. И тем более не хранить несколько Bitmap одного и того же изображения!
2) уменьшать разрешение картинки перед изображением. типичное решение - скалить в меньшую сторону по размеру экрана. (Зачем нам показывать картинку 2500х2000, если у нас разрешение экрана к примеру на Nexus 4 1280x768 ? )
По этому по поводу есть официальная дока - Displaying Bitmaps Efficiently http://developer.android.com/training/d ... index.html

Это общие размышления которые могут подтолкнуть найти проблему конкретно в твоем приложении.

UPD. Есть мнение что byte[] smallImageBlob и byte[] normalImageBlob жрут много памяти, тем более normalImageBlob далее нигде не используется.
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Артем Дегтев
Сообщения: 74
Зарегистрирован: 27 янв 2014, 00:05

Re: Проблема Out Of Memory

Сообщение Артем Дегтев » 31 янв 2014, 19:14

anber писал(а):Собственно корень проблемы: smallImage это Drawable, а Drawable содержит внутри себя Bitmap.
Предположим Bitmap имеет размер 5 мегапикселей (типично разрешение для фотки с камеры), имеет размер = 2500х2000 пикселей, каждый пиксель весит 4 байта (aRGB), т.е. фотка размером 5 мегапикселей в оперативке займет 19 мегабайт.
Далее: на 1 процесс в андроиде выделяется в среднем 64 мегабайта, та что путем нехитрых математических операций получим что в память влезет 3 - 5 картинок большого размера.

Отсюда 2 вывода, как избавиться от OOME:
1) не хранить много ссылок на большие картинки. И тем более не хранить несколько Bitmap одного и того же изображения!
2) уменьшать разрешение картинки перед изображением. типичное решение - скалить в меньшую сторону по размеру экрана. (Зачем нам показывать картинку 2500х2000, если у нас разрешение экрана к примеру на Nexus 4 1280x768 ? )
По этому по поводу есть официальная дока - Displaying Bitmaps Efficiently http://developer.android.com/training/d ... index.html

Это общие размышления которые могут подтолкнуть найти проблему конкретно в твоем приложении.

UPD. Есть мнение что byte[] smallImageBlob и byte[] normalImageBlob жрут много памяти, тем более normalImageBlob далее нигде не используется.
Так самое интересное что в базе хранится, только Блоб данные smallimage, a smallimage имеет размер 109х190. Функция достает отлично, и если доставать картинку с базы, но в хендлер отправлять другую, с ресурсов напрмер, ООМЕ нет, но хотя картинка и удачно достается, если ее отправлять в хендлер, то выскакивает.... день ломаю голову, не могу сделать....

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Проблема Out Of Memory

Сообщение anber » 31 янв 2014, 19:41

Если вдумчивое чтение исходников не помогает тогда могу посоветовать только МАТ ( Eclipse Memory Analyzer )
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Ответить