Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6359077
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T23:28:18+00:00 2026-05-24T23:28:18+00:00

My application shows an AlertDialog with a ListView inside. Everything worked fine bun then

  • 0

My application shows an AlertDialog with a ListView inside. Everything worked fine bun then I decided to test this for memory leaks. After running the app for some time I opened MAT and generated Leak Suspects report. MAT found several similar leaks:

One instance of “com.android.internal.app.AlertController$RecycleListView” loaded by “<system class loader>” occupies …

I spent a lot of time searching for the reason of this leak. Code review didn’t help me and I started googling. That’s what I found:

Issue 5054: AlertDialog seems to cause a memory leak through a Message in the MessageQueue

I decided to check whether this bug reproduces or not. For this purpose I created a little program which consists of two activities. MainActivity is an enrty point. It contains only a buttons which runs LeakedActivity. The latter just shows an AlertDialog in its onCreate() method. Here’s the code:

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViewById(R.id.button).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(
                    new Intent(MainActivity.this, LeakedActivity.class));
            }
        });
    }
}

public class LeakedActivity extends Activity {
    private static final int DIALOG_LEAK = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
            showDialog(DIALOG_LEAK);
        }
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        if (id == DIALOG_LEAK) {
            return new AlertDialog.Builder(this)
                .setTitle("Title")
                .setItems(new CharSequence[] { "1", "2" },
                    new OnClickListener() {
                        private final byte[] junk = new byte[10*1024*1024];

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // nothing
                        }
                    })
                .create();
        }
        return super.onCreateDialog(id);
    }
}

MAT reports this application leaks com.android.internal.app.AlertController$RecycleListView every time the AlertDialog is dismissed and the LeakedActivity is finished.

I can’t find any error in this small program. It looks like a very simple case of using AlertDialog and it must work well but seems it doesn’t. So I’d like to know how to avoid memory leaks when using AlertDialogs with items. And why hasn’t this problem been fixed yet? Thanks in advance.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T23:28:18+00:00Added an answer on May 24, 2026 at 11:28 pm

    (2/12/2012): see UPDATE below.

    This problem is not actually caused by the AlertDialog but more related to the ListView. You can reproduce the same problem by using the following activity:

    public class LeakedListActivity extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Use an existing ListAdapter that will map an array
        // of strings to TextViews
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mStrings));
        getListView().setOnItemClickListener(new OnItemClickListener() {
            private final byte[] junk = new byte[10*1024*1024];
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
            }
        });     
    }
        private String[] mStrings = new String[] {"1", "2"};
    }
    

    Rotate the device several times, and you’ll get OOM.

    I haven’t got the time to investigate more on what is the real cause (I know what’s happening but not clear why it’s happening; can be bug, or designed). But here’s one workaround that you can do, at least to avoid the OOM in your case.

    First, you’ll need to keep a reference to your leaked AlertDialog. You can do this in the onCreateDialog(). When you’re using setItems(), the AlertDialog will internally create a ListView. And when you set the onClickListener() in your setItems() call, internally it will be assigned to the ListView onItemClickListener().

    Then, in the leaked activity’s onDestroy(), set the AlertDialog‘s ListView‘s onItemClickListener() to null, which will release the reference to the listener an make whatever memory allocated within that listener to be eligible for GC. This way you won’t get OOM. It’s just a workaround and the real solution should actually be incorporated in the ListView.

    Here’s a sample code for your onDestroy():

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(leakedDialog != null) {
                ListView lv = leakedDialog.getListView();
                if(lv != null)  lv.setOnItemClickListener(null);
        }
    }
    

    UPDATE (2/12/2012): After further investigation, this problem is actually not particularly related to ListView nor to OnItemClickListener, but to the fact that GC doesn’t happen immediately and need time to decide which objects are eligible and ready for GC. Try this:

    public class MainActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            // this will create reference from button to 
            // the listener which in turn will create the "junk"
            findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                private byte[] junk = new byte[10*1024*1024];
                @Override
                public void onClick(View v) {
                    // do nothing
                }
            });
        }
    }
    

    Rotate a couple of times, and you’ll get the OOM. The problem is after you rotate, the junk is still retained because GC hasn’t and can’t happen yet (if you use MAT, you’ll see that this junk is still retained by the button’s listener deep down from the GCroot, and it will take time for the GC to decide whether this junk is eligible and can be GCed.) But at the same time, a new junk needs to be created after the rotation, and because of the mem alloc size (10M per junk), this will cause OOM.

    The solution is to break any references to the listener (the junkowner), in this case from the button, which practically makes the listener as a GCroot with only short path to the junk and make the GC decide faster to reclaim the junk memory. This can be done in the onDestroy():

    @Override
    protected void onDestroy() {
        // this will break the reference from the button
        // to the listener (the "junk" owner)
        findViewById(R.id.button).setOnClickListener(null);
        super.onDestroy();
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This code works in a windows forms application (it shows the preview) but not
In my application I am trying to use a ListView inside a PopupDialog .
I am porting a Delphi application to FPC/Lazarus and this application shows info in
I have an application that shows a list of items. The user can click
I have a C# application which shows the current time in a transparent .NET
I've got a simple application that shows pictures dragged onto it. I'd like the
I'm developing a web application that shows some controls and descriptions dynamically (I don't
I want to make an android application that shows a listing of applications (downloaded
I'm building a web application that shows users interesting visualizations of their Gmail activity
I have a simple HTML (as HTA) application that shows strange behavior on Windows

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.