gpt4 book ai didi

groovy - Groovy Abstract ConcurrentMap 中的错误?

转载 作者:行者123 更新时间:2023-12-01 23:29:17 24 4
gpt4 key购买 nike

AbstractConcurrentMap是Groovy中的核心类,它用于存储在运行时添加到Groovy类中的动态属性。我正在使用 Grails 2.1.2 和 Groovy 1.8.8,但我认为所有 Groovy 版本中都存在该问题(链接的源代码适用于 Groovy 版本 2.4.3)。

问题发生在内部类Segment的put()方法(第 105 行):

  • 当当前计数大于 map 阈值 a rehash() 时发生。现在棘手的部分是,Map 保存对对象的软引用和 rehash()验证这些引用。因此,当 GC 丢弃软引用时,生成的段不会扩展(正如 put() 方法中所假设的那样)。

  • last line of rehash()段内部计数器更新count = newCount(这是“事件”未丢弃引用的数量,可以小于如上所述的先前计数)

  • rehash()之后完成后,put()方法继续,但有问题的部分是,它忽略内部 count 的先前设置,并在行 124 上的每种情况下设置先前的 count+1 值。 , 143159

因此正在执行以下步骤:

  1. map 状态:阈值 = 786432;计数=786432
  2. 新元素已插入到 map 中:count = 786433;阈值=786432
  3. 因为新计数将大于阈值 rehash()发生了
  4. rehash() 发现,大多数对象都被垃圾收集,因此它不会增加 Segment 的大小,但无论如何它会将所有对象从一个表复制到另一个表(System.arrayCopy())。
  5. rehash() 将内部计数设置为新值,该值较小,因为许多对象被垃圾回收(软引用),例如:count = 486 000
  6. put()继续,忽略 count = 486 000 并将计数设置为 count = 786433
  7. 插入了另一个元素,但是在这种状态下,计数仍然大于阈值,因此再次进行重新哈希
  8. 从现在开始,添加到 map 的每个元素都会触发 rehash() ,这对性能有巨大影响。

当这种情况发生在多线程环境中时,所有其他线程都在等待(停放)lock(),直到 rehash() 和 put() 完成(然后下一个线程再次执行 rehash())。您可以想象这对性能有何影响......

我不明白这个错误如何能够在这么多版本中存在而没有人注意到,尽管该类被广泛使用。也许我错过了什么?

建议的解决方案:

重新哈希完成后更新 c 变量。在第 105 行和第 106 行之间添加:

c = count + 1

最佳答案

Groovy JIRA 上报告了该错误 https://issues.apache.org/jira/browse/GROOVY-7448现在已修复。

Fix Version/s:
2.4.4, 2.5.0-beta-1

关于groovy - Groovy Abstract ConcurrentMap 中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30593191/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com