Java:对象池和哈希集

标签 java garbage-collection duplicates set pooling

让我们假设以下类(class)...

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 插入和回收实例之前测试重复项的最有效方法是什么?

最佳答案

What happened with those "duplicate" instances? Are they "lost" and garbage collected?

是的,在 while (there-is-data) 的当前迭代完成后,这些将立即有资格进行 GC

If I wanted to keep those instances available in pool, what would be the most effective way to test for duplicates before inserting using addAll and recycling instances?

如果插入元素,

Set.add 返回 true;如果元素重复,则返回 false。所以你可以用

替换 addAll
for (Foo f : buffer) {
  if (!foos.add(f)) {
    // handle duplicate
  }
}

不会对性能造成影响,因为 addAll 执行相同的操作 - 迭代并逐一添加。

关于Java:对象池和哈希集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56103327/

相关文章:

java - h2 数据库 : Unsupported database file version or invalid file header in file

java - 如何从文件读取器中删除某些值(使用 ArrayList)?

java - JDialog 永远不会被垃圾回收

java - Java 中 Finalize() 操作的顺序

java - Java中如何检测字符串中的重复单词?

java - 带有值提取器的 ObservableMap?

java - 如何停止 Android 中的 Activity ?

java - 垃圾收集器 - 用于大文件的日志分析器

mysql - sql中产生重复数据

MySQL 查询删除重复行