【问题标题】:Java Garbage Collection BehaviorJava 垃圾收集行为
【发布时间】:2018-08-14 05:04:54
【问题描述】:
Android 设备上的垃圾收集器是只收集孤立的并且它认为太大的对象,还是收集所有孤立的对象而不考虑大小?
我正在做一个测试,我在堆栈中快速推送和弹出一个 Activity,然后查看堆。
如果有问题的 Activity 不包含代码,那么我最终会在堆转储中显示它的几个实例,即使在强制 GC 之后也是如此。
但是,如果我向该活动添加一个大变量(如大字节数组),那么 GC 似乎会按预期/预期运行。
【问题讨论】:
标签:
java
android
memory-leaks
garbage-collection
【解决方案1】:
垃圾收集器不关心他们收集的对象的大小。他们是不分青红皂白的。如果 GC 检测到一个对象不可达,它就会收集它。
您可能观察到的是不同的效果。典型的垃圾收集器仅在 JVM 确定有足够的垃圾值得收集时运行。问题是集合的工作量有两部分:
- 查找无法访问的对象
- 收集无法访问的对象
在典型的现代收集器中,查找不可达对象涉及遍历和标记所有可达对象:不可达对象是未标记的对象。然后收集不可达对象通常通过移动所有可达对象来完成。
这意味着 GC 所做的工作与非垃圾的数量成正比。因此,如果垃圾与非垃圾的比率很高,GC 将最有效地工作。最简单的衡量标准是堆满或接近满时。
所以您可能看到的是分配较大对象导致堆更快填满,并触发 GC 运行。当对象很小时,堆不会填满,GC 不会运行(还)。
至于“强制”GC,System.gc() 调用的行为是高度特定于平台的。在某些平台上,它会触发完整的 GC,而在其他平台上,它绝对不会做任何事情......以及介于两者之间的各个点。
【解决方案2】:
最终它会收集所有东西,无论大小。它在符合收集条件后收集的内容是特定于实现的,不应依赖。