OutOfMemoryError when using RealmRecyclerViewAdapter
ahmadmuflih opened this issue · 17 comments
i'm just working with these realm android adapters, and i have successfully implemented RealmBaseAdapter adapter, but now i'm having OutOfMemoryError when trying to implement RealmRecyclerViewAdapter. *I'm using Realm 3.0 and realm android adapters 2.0
Here is my code :
Adapter:
`
public class KontakAdapter extends RealmRecyclerViewAdapter<User,KontakAdapter.Holder> {
private OnKontakSelectedListener onKontakSelectedListener;
public KontakAdapter(OrderedRealmCollection<User> data, OnKontakSelectedListener onKontakSelectedListener) {
super(data,true);
this.onKontakSelectedListener = onKontakSelectedListener;
setHasStableIds(true);
}
public void setOnKontakSelectedListener(OnKontakSelectedListener onKontakSelectedListener) {
this.onKontakSelectedListener = onKontakSelectedListener;
}
@Override
public Holder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.kontak_list, viewGroup, false);
return new Holder(view);
}
@Override
public void onBindViewHolder(final Holder holder, int position) {
final User kontak = getItem(position);
holder.nama.setText(kontak.getName());
holder.no_hp.setText(kontak.getPhoneNumber());
String type="";
if(kontak.getType()==1){
type="Owner";
}
else{
type="Non Owner";
}
holder.type.setText(type);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(onKontakSelectedListener != null)
onKontakSelectedListener.onSelected(kontak);
}
});
}
@Override
public long getItemId(int position) {
return getItem(position).getId();
}
@Override
public int getItemCount() {
return getItemCount();
}
public static class Holder extends RecyclerView.ViewHolder{
View itemView;
TextView nama;
TextView no_hp;
TextView type;
public Holder(View itemView) {
super(itemView);
this.itemView = itemView;
nama = (TextView) itemView.findViewById(R.id.nama_kontak);
no_hp = (TextView) itemView.findViewById(R.id.no_hp_kontak);
type = (TextView) itemView.findViewById(R.id.type_kontak);
}
}
public interface OnKontakSelectedListener{
void onSelected(User kontak);
}
}`
Activity
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.list_user); KontakAdapter imageAdapter = new KontakAdapter(users,this); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(imageAdapter);
Layout
<android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:id="@+id/list_user"/>
It seems you have leaks somewhere maybe you can check the leaks first? Also, check if all the Realm instances are closed properly especially those in the background thread.
Facing the similar issue. I have profiled my code and there is no memory leak. Infact I have tested with the single activity and recyclerview in it and without binding any view, using only one instance of realm and maintained the lifecycle as per documentation provided by realm .
Realm object allocation keep increasing memory and it never releases the memory.
Don'n know this is issue from core Realm update or realm-adapter.
@sandeshlasnapure can you share your project with us? to help@realm.io ? thanks a lot!
ok. Will share you my demo project.
i just updated my realm to 3.1.1 and the error was changed, and the problem is this code :
@Override public int getItemCount() { return getItemCount(); }
and i just removed it to make my code better
@beeender any update?
@sandeshlasnapure I did check on your project, but I think your problem is more like the usage of loading images with glide but not Realm. If you disable code ContributorsAdapter.java
line 72-74, you can see the memory usage is not growing anymore. Maybe you can check this?
@beeender thanks for quick reply. I did check with the glide and without glide. The allocation issue is still there. Even if am not binding the data to adapter in onBindViewHolder realm still holds the memory.
Do I need to optimise my code?
Am I binding the data in correct way?
Is there any way to avoid OOM with realm?
I have tested the number of Realm defaultinstance count and seems fine as per document.
Should I follow another approach to define instances?
Please provide feedback.
Thanks.
@sandeshlasnapure So even you disable the image loading code, you can still see the OOM? How did you reproduce it? by pull-to-refresh many times? I am asking since i tried that (1. removing image loading 2. pull-to-refresh many times 3. click the gc button), i haven't seen abnormal things in the memory monitor.
Yes, while adding the items by pull-to-refresh many times you will notice the allocation keeps increasing.
That's the way I have reproduced the issue (Demo and Production code).
Also I have shared some screenshots, in which you can see the allocation keeps rising.
If you are not able to reproduce this issue again, let me know, will again analyse my heapdump for my production build and let you know.
Thanks.
So in your test (without loading the images with Glide), "allocation keeps rising" even you manually triggers Garbage Collection?
Yes, without loading the images allocation keeps rising. And when I trigger Garbage Collection there is no huge impact on memory.
In recycler adapter realm should free object references if we are not accessing the data from realmresult.
And I have also added the recycler pool limit to 30 items.
@sandeshlasnapure Got it. I will check it again.
@beeender thanks, please suggest any optimisation that I could do in my recyclerview or adapter.
Because I have to use the adapter with glide.
I have five fragments in viewpager, loading all 5 at the same time, all having same sort of layout with images with it.
Any suggestion would be helpful for me.
Thanks again.
@sandeshlasnapure How to use glide is beyond the topic for this repository. I think stackoverflow.com is a better place to ask and I am sure you can get a better answer there.
I will only focus on the Realm side leaks if there is any.
@sandeshlasnapure I did check the project you sent to us again.
What I changed in the project:
- Disable the image loading with Glide which should not be related with the topic of this issue - realm side leaks
- post a event to refresh the RecycleView every 100ms which is just a faster emulation of pull-to-refresh many times.
The changes can be found in the attached patch file.
changes.zip
So when the app starts:
java heap:
native heap:
after 20 mintues:
native heap:
I cannot see a clear leak there ... Maybe there is something wrong with my testing? Please let me know if there is anything wrong with my reproduce steps.
close due to no response