【发布时间】:2019-09-29 21:09:36
【问题描述】:
让我们假设以下课程...
class Foo {
private Bar1 bar1;
private Bar2 bar2;
// many other fields
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Foo foo = (Foo) o;
if (!bar1.equals(foo.getBar1()) return false;
if (!bar2.equals(foo.getBar2()) return false;
// etc...
}
@Override
public int hashCode() {
int result = bar1.hashCode();
result = 31 * result + bar2.hashCode();
// etc...
}
// setters & getters follow...
}
每分钟创建、处理数千个 Foo 实例,然后在池中回收。工作流程如下:
Set<Foo> foos = new THashSet<>();
while (there-is-data) {
String serializedDataFromApi = api.getData();
Set<Foo> buffer = pool.deserializeAndCreate(serializedDataFromApi);
foos.addAll(buffer);
}
processor.process(foos);
pool.recycle(foos);
问题是不同缓冲区之间可能存在重复的 foo 对象(具有相同的值)。这些被具体化为 Foo 的不同实例,但是在调用 foos.addAll(buffer) 时它们被认为是相等的。
我的问题是:
- 那些“重复”实例发生了什么?
- 它们是否“丢失”并被垃圾收集?
- 如果我想将这些实例保留在池中,那么在插入之前使用 addAll 和回收实例测试重复项的最有效方法是什么?
【问题讨论】:
-
只是好奇 - 为什么你需要所有这些?如果
Foo的实例是短暂的,那么这些实例不会留下年轻空间,因此会很快被收集。你的方法保证这些迟早会被转移到伊甸园空间。当您稍后重新使用这些并进行修改时,它会将整个区域标记为脏。我建议您对此池进行适当的测试。如果您编写(或编写)微基准测试,然后仔细检查它会测试您稍后将拥有的内容 - 对象位于伊甸园空间中并且不时修改。 -
当您不想删除重复项时,只需使用
List。
标签: java garbage-collection duplicates set pooling