U
U
Username2016-07-27 09:20:42
Android
Username, 2016-07-27 09:20:42

How to fix memory leak when replacing fragments?

There is a side curtain with a menu. When you click on the menu, the fragment with content changes to another one. I don’t store links to fragments anywhere, every time I change I create a new one. At the first couple of switches, everything happens as intended. The old fragment is removed by the collector, and the new one takes its place. That is, what happens to the memory is something like that, 28 MB is occupied, then I replace the fragment, drops to 19, then increases to the same 28. But after switching a little through the menu items, the memory stops being released and switching between two items, the operative flies up to 100 MB or even more .
The code for changing fragments and the fragment itself is below

private fun showEventBoard() {
        setTitle(R.string.event_board)
        supportFragmentManager.beginTransaction()
                .replace(R.id.main_content, MainEventBoardFragment(), EVENT_BOARD_FRAGMENT_TAG)
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .commit()
    }

    private fun showFavoriteEventBoard() {
        setTitle(R.string.favorites)
        supportFragmentManager.beginTransaction()
                .replace(R.id.main_content, FavoriteEventBoardFragment(), FAVORITE_EVENT_BOARD_FRAGMENT_TAG)
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .commit()
    }

abstract class EventBoardFragment : Fragment(), SubscriberChangesFavorite<EventInfo> {

    protected var createFilter = false
    protected var eventBoardView: EventBoardView? = null
    protected var filterBlock: FilterEventBoard? = null
    protected var adapter: AdapterEventBoard? = null
    protected var loaderEvents: LoaderEvents? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (eventBoardView != null)
            return
        adapter = AdapterEventBoard(ControllerBehaviorEventViewHolder(this))
        loaderEvents?.loadAllEvents { events ->
            if (events != null)
                for (e in events)
                    adapter?.addItem(e)
        }
    }

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        if (eventBoardView != null)
            return eventBoardView?.rootView
        val root = inflater?.inflate(R.layout.event_board, container, false)
        eventBoardView = EventBoardView(root!!)
        eventBoardView?.setRecyclerViewAdapter(adapter!!)
        if (createFilter) {
            filterBlock = createFilter()
            val v = filterBlock?.getView()
            if (v != null)
                eventBoardView?.addDynamicElement(v)
        }
        setHasOptionsMenu(true)
        return root
    }

    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
        if (createFilter)
            inflater?.inflate(R.menu.menu_main_activity, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        if (item?.itemId == R.id.filter) {
            if ((filterBlock?.showFilter ?: false))
                filterBlock?.hideFilterDialog()
            else
                filterBlock?.showFilterDialog(DataManager.getInstance().userData.filterInfo)
        }
        return super.onOptionsItemSelected(item)
    }

    protected abstract fun createFilter(): FilterEventBoard
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Ershov, 2016-08-04
@alaershov

Get to the point where you think your memory is gone. Run the garbage collector a couple of times, just to be sure. If the memory is still occupied inadequately a lot - make a memory dump. Then use a dump analyzer, such as Eclipse's Memory Analyzer Tool, to see which objects are taking up memory and why they are not garbage collected.

M
Maxim Firsov, 2016-08-04
@FirsofMaxim

See if there are links here:

protected var createFilter = false
    protected var eventBoardView: EventBoardView? = null
    protected var filterBlock: FilterEventBoard? = null
    protected var adapter: AdapterEventBoard? = null
    protected var loaderEvents: LoaderEvents? = null

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question