Skip to content

Throwing OutOfMemoryError "Could not allocate JNI Env" #1394

@captain-miao

Description

@captain-miao
compile 'com.github.captain-miao:recyclerviewutils:1.2.1-SNAPSHOT'

    @BindingAdapter({"compressImageUrl"})
    public static void loadImageCompress(ImageView imageView, String url) {
        //recycle bitmap
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof BitmapDrawable) {
            imageView.setImageDrawable(null);
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            Log.d(TAG, "recycle bitmap, w:" + bitmap.getWidth() + ", h:" + bitmap.getHeight());
            bitmap.recycle();
        }
        Picasso.with(imageView.getContext().getApplicationContext())
                .load(url)
                .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
                .placeholder(R.drawable.ic_image_load_place_holder)
                .config(Bitmap.Config.RGB_565)
                .tag(PicassoOnScrollListener.TAG)
                .into(imageView);
}

fast scroll RecycleView, load image more and more and more...

 ** MEMINFO in pid 4695 [com.github.captain_miao.agera.tutorial] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap    26019    25972        0        0    37376    33872     3503
  Dalvik Heap   172734   172632        0        0   196608   181382    15226
 Dalvik Other     5184     5184        0        0 
W/art: Throwing OutOfMemoryError  "Could not allocate JNI Env"
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.github.captain_miao.agera.tutorial, PID: 18267
    java.lang.OutOfMemoryError: Could not allocate JNI Env
        at java.lang.Thread.nativeCreate(Native Method)
        at java.lang.Thread.start(Thread.java:1063)
        at com.squareup.picasso.Dispatcher.<init>(Dispatcher.java:102)
        at com.squareup.picasso.Picasso$Builder.build(Picasso.java:867)
        at com.github.captain_miao.agera.tutorial.helper.PicassoBinding.loadImageCompress(PicassoBinding.java:77)
        at com.github.captain_miao.agera.tutorial.databinding.RecyclerItemViewBinding.executeBindings(RecyclerItemViewBinding.java:114)
        at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:355)
        at com.github.captain_miao.agera.tutorial.recycleview.VehicleListAdapter.onBindItemViewHolder(VehicleListAdapter.java:45)

Try use pauseTag() from this blog image-loading-with-picasso,it's working.

The solution: from Picasso Singleton Usage

if you use the builder you should create your own singleton to hold your instance of Picasso and clean it up when your done. Do not use builder every time that you use picasso because it creates a new instance. I believe that Picasso.with(context) just takes your context and calls getApplicationContext and stores a singleton instance of picasso with the application context.

use:

        Picasso.with(imageView.getContext().getApplicationContext())
                .load(url.replace("large", "bmiddle"))
                .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
                .placeholder(R.drawable.ic_image_load_place_holder)
                .config(Bitmap.Config.RGB_565)
                .tag(PicassoOnScrollListener.TAG)
                .into(imageView);

not:

Picasso.Builder builder = new Picasso.Builder(imageView.getContext().getApplicationContext());

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions