Out Of Memory Error When loading more images in Glide

27,275

Solution 1

  • I solved this issue by removing nested scroll view placed above recyclerview. Why OutOfMemory error occurred means, when loading more than 200 images in home page, it is loading all 200 images because of using nested scroll view above recyclerview.

  • So I can't check the logcat image view width and height one by one in adapter.

  • After removed nested scroll view fixed out of memory error.because it will load only 3 images displayed in device when coming to home activity.

  • Also check this, how to use scroll instead of nested scroll view.

Solution 2

This is not an exact solution to your problem, but you need to keep these things in mind while loading images in a list using Glide.

The main threatening part of your problem is the image size. The image you're getting is almost 1mb each! Which is in fact too large for displaying them into a list having 300+ items. So if you're doing the server side too, its always recommended to have the images in several different sizes.

For example, in case of showing a friend list along with their profile pictures, I would suggest you get the whole list first from the server. Then fetch all of the profile images and store them locally. Then populate the ListView. And the most important part is while uploading a profile picture of an user to the server, after uploading it, the server needs to keep several sizes of it e.g. low, mid and high res version. So that while serving the profile picture urls for the ListView the server might provide the images with low res as they'll be used most likely for thumbnails.

Using RecyclerView instead of ListView is a good call too. But it won't solve the problem you've here when you're in a low-end device.

OMM has nothing to do with you can solve programatically. You need to resize your image to a lower res version.

You can check for the Glide's caching mechanism too. I would suggest you use the caching strategy so that every time you don't have to load the image from server.

Good luck.

Solution 3

  1. Make sure the ImageView has match_parent or fixed dp as dimensions wrap_content makes Glide load full resolution Bitmaps.
  2. .placeholder() shows an image instead of empty space while loading large bitmap
  3. .thumbnail(float) loads a downsampled version fast while the bigger image is loading in the background
  4. Also look around the Glide issues, maybe you find something helpful.

Solution 4

Using Glide doesn't guarantee no Out of Memory errors, you need to use several small steps to reduce the probability to not get OOM's.

Step 1: Understand the caching mechanism in Glide

Step 2: I prefer to load thumbnails into recyclerview

Glide  
    .with( context )
    .load( UsageExampleGifAndVideos.gifUrl )
    .thumbnail( 0.1f )
    .into( imageView2 );

Remember to always request small size image if bigger or HD images are not required.

Solution 5

Use recyclerView instead of ListView. It reusable single item for rendering items. I am using glide with recyclerView where i am loading wallpapers with 100+ items.

In ListView every time you are creating view, if you have 100+ view and it will create 100+ views where as in recyclerview it creates how many visible items are there in screen +2.

Share:
27,275
Steve
Author by

Steve

Updated on July 09, 2022

Comments

  • Steve
    Steve almost 2 years

    Edited:

    • In my application, I am loading more than 300 images in home page. I used glide to load images. I'm getting Out of Memory Error.

    I have used large heap true in manifest :

    android:largeHeap="true"
    

    Glide Version:

    compile 'com.github.bumptech.glide:glide:3.7.0'
    

    Device/Android Version:

    Nexus Device 6.0 version

    Every images I'm getting from Json would be 800kb to 1mb.

    activity_layout:

    <RelativeLayout
        android:id="@+id/home_layout_bottom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/home_layout_top_recycler"
        android:layout_margin="5dp">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_list_tab_home_recycler"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:scrollbars="vertical"
            android:visibility="visible" />
    
        <TextView
            android:id="@+id/no_user_posts_item_tv_recycler"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/rv_list_tab_home_recycler"
            android:layout_marginTop="80dp"
            android:layout_centerHorizontal="true"
            android:text="@string/txt_no_posts_available"
            android:textColor="@color/txt_common_black"
            android:textSize="@dimen/txt_size" />
    </RelativeLayout>
    

    adapter code:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
    
        final HomePostItems rowItem = getItem(position);
    
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {
    
            convertView = mInflater.inflate(R.layout.lv_adapter_post_items_layout, null);
    
          holder = new ViewHolder();
    
          holder.ivPostedImage = (ImageView) convertView.findViewById(R.id.iv_posted_img);
    
    
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
    
          ..................
    
              Glide.with(context).load(rowItem.getPosteduserpostimage())
                            .placeholder(R.drawable.golive_load_image).error(R.drawable.golive_cancel_image)
                            .override(600, 200)
                            .into(holder.ivPostedImage);
    

    adapter_layout.xml:

    <RelativeLayout
        android:id="@+id/rl_lv_user_post_adapter_img_holder_home"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_marginLeft="1dp"
        android:layout_marginRight="1dp"
        android:layout_below="@+id/tv_user_posted_msg_post_items_home" >
    
        <ImageView
            android:id="@+id/iv_posted_img_home"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:scaleType="fitXY"
            android:background="#ffffff"
            android:contentDescription="@string/cont_desc"/>
    </RelativeLayout>
    

    Logcat:

    Request threw uncaught throwable
    java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Failed to allocate a 6365196 byte allocation with 865912 free bytes and 845KB until OOM
    at java.util.concurrent.FutureTask.report(FutureTask.java:94)
    at java.util.concurrent.FutureTask.get(FutureTask.java:164)
    at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor.afterExecute(FifoPriorityThreadPoolExecutor.java:96)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1121)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
    at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
    Caused by: java.lang.OutOfMemoryError: Failed to allocate a 6365196 byte allocation with 865912 free bytes and 845KB until OOM
    at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
    at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
    at com.bumptech.glide.load.resource.bitmap.Downsampler.decodeStream(Downsampler.java:329)
    at com.bumptech.glide.load.resource.bitmap.Downsampler.downsampleWithSize(Downsampler.java:220)
    at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:153)
    at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:50)
    at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:19)
    at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:39)
    at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:20)
    at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeBitmapWrapper(GifBitmapWrapperResourceDecoder.java:121)
    at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeStream(GifBitmapWrapperResourceDecoder.java:94)
    at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:71)
    at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:61)
    at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:22)
    at com.bumptech.glide.load.engine.DecodeJob.decodeFromSourceData(DecodeJob.java:190)
    at com.bumptech.glide.load.engine.DecodeJob.decodeSource(DecodeJob.java:177)
    at com.bumptech.glide.load.engine.DecodeJob.decodeFromSource(DecodeJob.java:128)
    at com.bumptech.glide.load.engine.EngineRunnable.decodeFromSource(EngineRunnable.java:122)
    at com.bumptech.glide.load.engine.EngineRunnable.decode(EngineRunnable.java:101)
    at com.bumptech.glide.load.engine.EngineRunnable.run(EngineRunnable.java:58)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
    at java.lang.Thread.run(Thread.java:818) 
    at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
    

    I don't know how to fix this OOM issue. Please share your suggestion, if you have already familiar with this issue.