列出添加/添加浅表副本和GC

时间:2018-06-24 22:38:47

标签: java list garbage-collection copy

我有table(factor(v2, levels = v1)) # A B C D E # 0 2 2 1 0 ClassA和一个线程ClassBB将要求ClassA从数据库服务器收集数据。这样做之后,ClassB将使用ClassAClassB复制数据。 我了解List.add元素是ClassA的浅表副本(仅副本引用)。

复制后,ClassB将超出范围,GC可能会丢弃它。

  1. 即使在ClassB中创建的对象仍被ClassB引用,GC也会处置ClassB吗?

  2. 还是将ClassA保留在内存中?

  3. 或仅保留其他类引用的对象,并且不处理任何未使用的对象。

1 个答案:

答案 0 :(得分:0)

垃圾收集器处理对对象的引用,其分析将找到代码维护引用的所有对象。

要回答您的三个问题:

  1. 如果您的代码仍引用ClassA,则将不会收集其引用的任何对象(无论创建哪个类)。
  2. ClassB不在范围内,这意味着您的代码不再引用它。因此,它有资格收集。这种情况何时发生尚未定义。
  3. 这个问题尚不完全清楚。收集器将收集任何未(直接或间接)引用的对象。

提供更多背景知识来帮助您理解这一点。当普通GC(有些可能不这样做)启动时,它们会创建所谓的根集。这是可从您的代码直接访问的所有对象的列表。这是通过扫描所有初始化的类(用于静态引用)以及寄存器和堆栈来创建的。对于CMS和G1,此根集用于执行初始标记阶段(与应用程序线程同时执行)。收集器将获取根集中的每个对象引用,并遍历其中的所有对象引用,以建立可从您的代码访问的对象的完整列表。如果无法访问对象,则不会对其进行标记。标记完成后(对于CMS和G1,这也需要停止标记阶段),收集器将具有可访问对象的精确列表。

对于年轻的一代收藏,有效对象被复制到幸存者空间或晋升为老一代。老一代的集合将更新活动对象之间空间的空闲列表,或者执行完整的压缩集合,重新定位对象以使它们在内存中都是连续的,从而消除碎片。

还有其他算法在做事上稍有不同(例如我工作的Azul的C4),但总体效果是相同的。