Возникает ошибка OutOfMemoryError

128
21 января 2020, 17:00

Вот возникает следующая ошибка при выполнении программы. Как мне ее избежать, помогите пожалуйста?

W/art: Throwing OutOfMemoryError "Failed to allocate a 51916812 byte allocation with 16777216 free bytes and 39MB until OOM"
    E/AndroidRuntime: FATAL EXCEPTION: Thread-10
                      Process: com.example.work, PID: 25823
                      java.lang.OutOfMemoryError: Failed to allocate a 51916812 byte allocation with 16777216 free bytes and 39MB until OOM
                          at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                          at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
                          at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:650)
                          at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:626)
                          at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:664)
                          at com.example.work.MainStudent$1.run(MainStudent.java:115)
                          at java.lang.Thread.run(Thread.java:760)
    W/AndroidRuntime: finished raiseRlimit, rlim_cur:4096  rlim_max:4096

 String sql2 = "SELECT photo1,photo2,photo3 FROM post where email ="+"'"+Login.User+"'";
                try {
                    rs = stmt.executeQuery(sql2);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    while (rs.next()) {
                        if(rs.getBlob("photo1") != null) {
                            Blob imageBlob = rs.getBlob("photo1");
                            binaryStream = imageBlob.getBinaryStream(1, imageBlob.length());
                            postImage.add(BitmapFactory.decodeStream(binaryStream));
                        }
                        else{
                            postImage.add(null);
                        }
                        if(rs.getBlob("photo2") != null) {
                            Blob imageBlob = rs.getBlob("photo2");
                            binaryStream = imageBlob.getBinaryStream(1, imageBlob.length());
                            postImage.add(BitmapFactory.decodeStream(binaryStream));
                        }
                        else {
                            postImage.add(null);
                        }
                        if(rs.getBlob("photo3") != null) {
                            Blob imageBlob = rs.getBlob("photo3");
                            binaryStream = imageBlob.getBinaryStream(1, imageBlob.length());
                            postImage.add(BitmapFactory.decodeStream(binaryStream));
                        }
                        else {
                            postImage.add(null);
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
Answer 1

Попробуйте уменьшить потребление памяти путём ухудшения качества по цвету и размеру:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.RGB_565;
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
Answer 2

Во-первых, уменьшить качество картинок в базе.

Во-вторых, вынести картинки в отдельную таблицу, а в списке писем оставить id изображения. Когда нужны будут картинки - селектить их не всей пачкой сразу, а по одной, обрезая размер до вменяемого, как уже советовали в комментариях, если они все же больше разрешения экрана/размеров вьюшке, в которой будет отображаться.

В-третьих, если первых двух пунктов не хватит, добавить в манифест в тег атрибут android:largeHeap="true". Он увеличит максимальное количество оперативной памяти для приложения

В-четвертых, повесить на поток "перехватчик неперхваченых исключений", т.к. OutOfMemory не ловится catch-ем. Реализовать Thread.UncaughtExceptionHandler и повесить его на основной поток

Thread.currentThread().setUncaughtExceptionHandler(this);

Тогда хотя бы можно среагировать и показать пользователю сообщение об ошибке, а не просто умереть

В-пятых, лучше не работать с картинками в основном потоке. Этот процесс может быть болезненным. Рекомендую взять библиотеку для загрузки изображений, например Picasso. Ее использование вынесет загрузки картинок в отдельный поток, она обработает OutOfMemory и любую другую ошибку при загрузке так, что программа продолжит работать, просто вместо нужной картинки подставят картинку ошибки. В общем, полезная штука :)

READ ALSO
не создаются папки из java idea через mkdir()

не создаются папки из java idea через mkdir()

Создаю папки в среде с относительным путем:

189
gesturedetector прокрутка

gesturedetector прокрутка

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

163
Анимация появления текстового символа

Анимация появления текстового символа

У меня есть svg изображение буквы А которая составлена из трех элементов: двух параллелограммов и прямоугольника - перекладины

267
Yii2 темизация. Как подставить только CSS?

Yii2 темизация. Как подставить только CSS?

Всем приветЕсть уже готовый проект

139