【问题标题】:Java: Disruptor: Should Disruptor be used only for POD datatypes?Java:Disruptor:Disruptor 是否应该只用于 POD 数据类型?
【发布时间】:2012-02-17 11:58:43
【问题描述】:

应该只对 POD 数据类型使用 Disruptor 吗?

我的意思是 Disruptor<T> 应该只用于 T 取值如 byte[], int[], etc 吗?

我的疑问是,如果我们使用具有Object 引用作为其成员变量的T,我们需要new 那些将位于堆上的成员变量。 这将再次导致缓存未命中,因为成员变量可能位于堆的完全独立的部分。

那么我认为Disruptor<T> 应该只用于属于一组普通旧数据类型 (POD) 的 T 是否正确?

问候, 虚拟机

更新:其他人可以看看这个问题吗?

更新2:

回复@Trisha

嗨,特丽莎,

您好。

我看到了你提到的链接。

com.lmax.ticketing.api.Message 继承自 javolution.io.Struct 并由来自 javolution.io.Structjavolution.io.Union 的元素组成,这使得 Message 可以在 C/C++ 之间进行互操作 对于从javolution.io.Struct/Union 继承的任何类,内存布局由Struct/Union 的成员的初始化顺序定义,并遵循与C/C++ 结构相同的wordSize 规则。

因此,本质上,您可以控制放入Disruptor 中的元素的内存布局。并且Message 的所有成员和子成员都是固定大小的,即没有任何动态内存(java.lang.Object

这也是我的观点,我们应该使用我们可以控制内存布局并且没有任何动态内存的元素。这样做是为了最大限度地减少缓存未命中。

假设,如果消息的一部分是java.lang.String,我们不知道 JIT 编译器会将那个字符串放在哪里。如果我正在访问EventHandler 中的Message.String,这可能会导致缓存未命中,因为字符串可能存在于完全不同的内存块中..

我说的对吗?

【问题讨论】:

  • 我认为您的问题是有效的,尽管措辞可能有误。我还不相信答案。如果您的事件对象的大小不固定,或者在“新”时间不确定,我看不出如何阻止垃圾收集器。

标签: disruptor-pattern


【解决方案1】:

您可以使用任何类型的对象作为事件,例如,请参阅https://github.com/mikeb01/ticketing 处的代码(例如 com.lmax.ticketing.web.RequestServlet) - 这使用 Message 作为 @987654323 中的对象@。

RingBuffer 使用调用Disruptor 构造函数时提供的EventFactory 预先填充了这些事件。因此,您只需在创建 RingBuffer 时创建它们的新实例,然后在 Disruptor 的整个生命周期中重复使用它们。同样,您可以在上述项目中看到一个示例。

【讨论】:

  • 嗨,Trisha,请参阅我在上述问题中的回复。谢谢。
  • 但是如果你的对象的大小是不确定的(例如包含其他对象——比如一个字符串),系统如何在初始化时“分配”适当的空间?
【解决方案2】:

我会说不,因为您编写的代码中没有说明任何限制。如果作者打算这样做,代码应该强制执行。

更新:你有一个答案:“不”。如果你再得到一百个“不”的答案,你还需要等待,以防黑天鹅出现吗?您是否有任何数据表明这是一个问题?

您是否认为所有缓存解决方案都会遭受同样的命运?我知道对任何其他缓存解决方案都没有这种限制。是否还有更多证据值得考虑?

【讨论】:

  • 对,代码应该以某种方式限制它并且没有限制,但是我对缓存未命中的怀疑呢?这就是使用 Disruptor 以最大限度地减少缓存未命中的重点。
  • 也许你的怀疑是没有根据的。也许实现者已经在他们的实现中考虑了这些事情。
  • 我希望是的。但我真的在寻找答案。
  • 对我来说,不作为答案很好。但我也想知道为什么它没有任何影响。
  • "...它将位于堆上。这将再次导致缓存未命中,因为成员变量可能位于堆的完全独立的部分...." - 此语句对我。有时必须有人打电话给新的。
猜你喜欢
  • 2012-05-06
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2011-02-26
  • 1970-01-01
相关资源
最近更新 更多