Android 验证为什么在第二次垃圾收集运行时仅对对象进行垃圾收集
出于学习目的,我目前正在尝试垃圾收集(Pixel 2,Android 10->Android 验证为什么在第二次垃圾收集运行时仅对对象进行垃圾收集,android,garbage-collection,Android,Garbage Collection,出于学习目的,我目前正在尝试垃圾收集(Pixel 2,Android 10->ART)。我对以下实验的观察结果是,CountActivity在第一次显式垃圾收集运行时从未被删除,但仅在第二次显式垃圾收集运行时被删除。我想了解为什么它在第一次运行时没有被删除。我假设这是由于某种代际垃圾收集,但我想验证一下。我如何“观察”垃圾收集的工作?例如,是否可以看到垃圾收集对堆进行分组的内部代 我的测试示例如下所示: MainActivity,其中显示一个按钮“ShowCountActivity” Count
ART
)。我对以下实验的观察结果是,CountActivity
在第一次显式垃圾收集运行时从未被删除,但仅在第二次显式垃圾收集运行时被删除。我想了解为什么它在第一次运行时没有被删除。我假设这是由于某种代际垃圾收集,但我想验证一下。我如何“观察”垃圾收集的工作?例如,是否可以看到垃圾收集对堆进行分组的内部代
我的测试示例如下所示:
MainActivity
,其中显示一个按钮“ShowCountActivity”CountActivity
当按下main Activity
中的“Show CountActivity”按钮时显示李>
CountActivity
CountActivity
将消失。现在我仍然想理解为什么需要运行两次垃圾收集
main活动
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)
}
}
class CountActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_count)
}
}
CountActivity
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)
}
}
class CountActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_count)
}
}
ART(Android运行时)使用的是所谓的a,它基本上是根据对象的创建时间创建对象桶(理论上,较新的对象更可能需要垃圾收集,因为所有临时对象(构建器、其他中间对象等)都在垃圾收集处)因此,垃圾收集不一定收集所有代的对象
以下是有关Android垃圾收集器工作原理的一些基本信息:
您可以通过在androidstudio中获取并分析堆转储来验证这一点,并注意到并没有从相关对象到任何GC根的路径
这里有一些关于GC细节的非常详细的文档(可能对从事艺术工作的人更有用,但信息仍然丰富——本节特别讨论了几代人的收藏):分析垃圾收集的确切类型和工作方式最好是通过分析它写入的日志记录来完成,这可以通过网站gceasy.io上的免费工具自动进行分析,该工具在他们的博客中对此进行了说明: 如果您想从日志中了解到需要进一步调查的问题(例如:内存泄漏、性能问题),您可能需要创建一个堆转储,并使用自定义代码分析您选择的所有对象和对象引用,例如: 或者可以通过类似ahat的web应用程序:
谢谢,但有没有办法真正检查一下情况是否属实?我真的很想看看(不是假设,但我也相信这是由于我的年龄)运行的是哪种类型的GC,如果可能的话,哪个对象在哪个bucket中。@stefan.at.wpf我可以想象最简单的方法是编写一个小型测试程序,并使用内置工具,如IDE@riggedCoinflip在调试器中看不到这一点。GC的某些部分在systrace中是可见的,但很难用O来解释ut更深层次的知识。而且它似乎只显示运行了哪种GC,而不是堆的外观。好的,感谢您的澄清,我不知道。到目前为止,我从未担心过垃圾收集。不过,您应该能够通过堆转储进行检查。请您共享您的GC日志文件,以便我们可以看到实际情况发生了什么事?当然。你能给我一些如何收集这些的提示吗?我猜你不仅仅是在谈论logcat条目,对吧?当你已经有了堆转储时,你应该能够找出对对象的引用确实存在。我没有理由假设堆转储是相同的。事实上,你已经声明它们不是,就像关于所讨论对象的存在至少存在这种差异。当在第一个转储中没有对它的引用时,我们不仅涉及垃圾收集器的工作方式,还涉及堆转储的创建方式。除了能够在堆转储中看到对象之外,还有其他后果吗?@Holger no,没有没有其他后果。它在第一个堆转储中,在第二个堆转储中消失,中间什么也没做。谢谢你的回复。你指的是哪些日志?logcat输出?是的,博客指的是包含更多信息的此页面