Android设备上的垃圾收集器是否仅收集孤立的对象并且认为它太大,还是收集所有孤立的对象而与大小无关?
我正在做一个测试,在其中我快速将Activity推入并弹出堆栈几次,然后查看堆。
如果有问题的活动不包含任何代码,那么即使强制执行GC,我也会在堆转储中显示该活动的多个实例。
但是,如果我向此活动添加一个大变量(如大字节数组),则GC似乎表现出预期/预期的表现。
答案 0 :(得分:2)
垃圾收集器不关注其收集的对象的大小。他们是不分青红皂白的。如果GC检测到无法访问的对象,它将收集该对象。
您可能观察到的是不同的效果。典型的垃圾收集器仅在JVM确定有足够的垃圾值得收集时才运行。问题在于集合的工作量包含两个部分:
在典型的现代收藏家中,找到不可访问的对象涉及遍历和标记所有可访问的对象:不可访问的对象是未标记的对象。然后,通常通过移动所有可到达的对象来完成收集不可到达的对象的操作。
这意味着GC所做的工作与非垃圾量成正比。因此,如果垃圾与非垃圾的比率很高,则GC将最有效地工作。最简单的方法是当堆已满或接近满时。
因此,您可能会看到的是,分配较大的对象会导致堆更早填充,并触发GC运行。当对象较小时,堆不会填满,并且GC也不会运行。
对于“强制” GC,System.gc()
调用的行为是高度特定于平台的。在某些平台上,它将触发完整的GC,而在其他平台上,它将完全不执行任何操作……并且介于两者之间。
答案 1 :(得分:1)
最终,无论大小如何,它都会收集所有内容。在变得难以收集之后,它所收集的内容是特定于实现的,因此不应依赖。