Проверьте, почему объект является только мусором, собранным во втором запуске сборки мусора - PullRequest
4 голосов
/ 29 марта 2020

В целях обучения я в настоящее время экспериментирую со сборкой мусора (Pixel 2, Android 10 -> ART). Мое наблюдение за следующим экспериментом состоит в том, что CountActivity никогда не удаляется при первом явном запуске сбора мусора, а только при втором явном запуске сбора мусора. Я хочу понять, почему он не удаляется при первом запуске. Я предполагаю, что это связано с какой-то сборкой мусора из поколения в поколение, но я хочу это проверить. Как я могу "посмотреть", что делает сборка мусора? Например, можно ли увидеть внутренние поколения, в которых сборщик мусора группирует кучу?

Мой тестовый пример выглядит следующим образом:

  1. MainActivity, который показывает кнопку «Показать» CountActivity "
  2. CountActivity, которое отображается при нажатии кнопки" Show CountActivity "в MainActivity.
  3. Я завершаю CountActivity, используя системный ключ возврата

После этого я принудительно запускаю сборщик мусора, собираю кучу. CountActivity все еще там. После принудительного запуска второго явного сбора мусора и повторного захвата кучи CountActivity исчезает. Теперь я все еще хочу понять, почему требуется два запуска сборки мусора.

MainActivity

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    setTheme(R.style.AppTheme)
    super.onCreate(savedInstanceState)

    setContentView(R.layout.activity_main)

    buttonStart.setOnClickListener {
      showCountActivity()
    }

  }

  private fun showCountActivity() {
    val intent = Intent(this, CountActivity::class.java)
    startActivity(intent)
  }

}

CountActivity

class CountActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_count)
  }
}

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

ART (Android RunTime) использует так называемый поколенный сборщик мусора , который в основном создает корзины объектов, основанные на том, когда эти объекты были созданы (на теории, что более новые объекты более вероятны необходимость в сборке мусора, поскольку именно там будут находиться все временные объекты (сборщики, другие промежуточные объекты и т. д. c.). Таким образом, сборка мусора не обязательно собирает все поколения объектов.

Вот некоторая базовая c информация о том, как Android работает сборщик мусора: https://developer.android.com/topic/performance/memory-overview

Это можно проверить, взяв и проанализировав дамп кучи в Android Studio и отмечая, что нет пути к каким-либо корням G C от рассматриваемого объекта.

Вот некоторая очень подробная документация о деталях G C (более вероятно, будет полезна для людей, работающих над Сам ART, но все же информативный - в разделе эргономика , в частности, немного обсуждается коллекция поколений) : https://source.android.com/devices/tech/dalvik/gc-debug

1 голос
/ 07 апреля 2020

Анализ точного типа и работы вашей сборки мусора лучше всего выполнить путем анализа записей, которые она записывает, которые можно автоматически проанализировать с помощью бесплатного инструмента на сайте gceasy.io, который иллюстрирует это в своем блоге:

https://blog.gceasy.io/2017/05/09/understanding-android-gc-logs/

Если вы узнаете из журналов, что у вас возникла проблема (например, утечка памяти, проблема с производительностью), которую вам нужно было для дальнейшего изучения, вы можете захотеть создать дампа кучи и проанализируйте все объекты и ссылки на объекты по вашему выбору, например, с помощью пользовательского кода:

https://rhye.org/post/advanced-android-heap-analysis/

Или, возможно, с помощью веб-приложения, такого как ahat:

https://android.googlesource.com/platform/art/+/master/tools/ahat/README.txt

...