我目前正在优化代码,定期从数据库重新加载大量数据。每次执行此操作时,一旦操作结束,就会创建并释放800k个对象以进行垃圾回收。
作为代码的一个优化,我想使用一个对象池来重用池中的对象并降低对垃圾收集的影响。我考虑过为此目的使用disruptor库,但遗憾的是我找不到任何最近的例子来处理借用和回馈池的对象。大多数示例都侧重于消息处理。
我现在的问题是,如果有任何示例项目/代码只在那里处理池,或者如果有人可以提供如何解决这个与破坏者的想法。
更新 我找到了this github repo,它基本上在后台使用disruptor实现了一个池化解决方案。
答案 0 :(得分:0)
对象池概念用于可以借用对象的地方(即调用borrow()),你应该将对象(即调用returnObject()方法)返回到池中 否则对象池将失败。 如果能够在不需要对象后再次将对象返回到池中,则尝试将其尝试。这将有很大帮助。
答案 1 :(得分:0)
我并不完全确定它真的是你需要的破坏者。以非常简单的方式
破坏者是让生产者和消费者沟通的一种方式 无锁,有效的内存处理。
更详细的答案(here)为您提供有关破坏者实施的内部运作的完整解释。
根据此问题陈述,您似乎在做什么:
...优化从中重新加载大量数据的代码 数据库定期。每次执行此操作~800k 创建和释放对象以进行垃圾收集......
为此,我只使用一种简单的缓存机制。如果您只加载一次数据,那么每次需要时都会为您的进程提供访问权限,GC负载将为它得到了优化。关于其他问题:
适当的缓存参数化可用于解决它们(驱逐,预读刷新,读取行为等)。
答案 2 :(得分:0)
破坏者的行为就像一个队列。物品必须按顺序移动。
普通池无法确保以获得的顺序释放项目。这意味着会发生很多堵塞,使用物品的时间最长的受害者。
如果你有N个线程在工作,你需要不超过N个项目。这是一个threadlocal的好地方,甚至在循环外部的线程堆栈(局部变量)上分配(如果需要,可以在参数中传递)。
现在,你的情况有点不同了。你已经知道它们来自一个地方,我想是一个数据库结果集。为什么不将行流式传输到N个处理程序池?您可能永远不需要分配超过N个项目来加载行并执行工作。
如果项目是局部变量,则jit将在线程堆栈上分配,而不是在堆中分配,并且gc税将被转义。
无论如何,流媒体比填充800'000实例和延迟处理更好。当它们是短暂的(如在流媒体中)时,GC税是最小的,因为它们都在年轻一代。