如何估计或计算ArrayBlockingQueue的大小

时间:2011-10-31 19:20:04

标签: java multithreading queue

作为标题,在我的模块中,我有一个阻止队列来传递我的数据。服务器可以生成的数据是大量的日志信息。为了避免影响服务器的性能,我编写了多线程客户端来使用这些数据并将它们保存在数据缓存中。因为数据可以每分钟大量生成,所以我很困惑,我应该初始化队列多少大小。而且我知道我可以设置我的队列策略,如果生成更多数据,我可以省略溢出部分。但是我在队列中创建了多少大小,以便尽可能多地保存这些数据。

你能给我一些建议吗?据我所知,这与我的服务器JVM堆栈大小有关。我的JVM中的单个日志数据???

2 个答案:

答案 0 :(得分:2)

让它“尽可能大”。例如,如果您可以使用高达1Gb的内存,那么将其大小分配为1Gb除以队列中对象的平均字节数。

如果我必须选择一个“合理”的号码,我会从10000开始。原因是,如果它增长到大于那个,那么增大它并不是一个好主意并且不会有太大帮助,因为显然日志记录要求超过了你的记录能力,所以是时候退出了客户端。

通过实验“调整”通常是最好的方法,因为它取决于您的应用程序的配置文件:

  • 如果您的应用程序活动中存在高点和低点,那么更大的队列将有助于“平滑”服务器上的负载
  • 如果您的应用程序具有相对稳定的负载,那么较小的队列适合作为较大的队列,只有延迟当客户端被阻止时不可避免的一点 - 您最好将其缩小并投入更多消耗工作的资源(几个日志记录线程)。

另请注意,非常大的队列可能会影响垃圾回收对释放内存的响应能力,因为它必须在每次运行时遍历更大的堆(队列中的所有对象),从而增加CPU和内存的负载

您希望尽量减小尺寸,而不会过多地影响吞吐量和响应速度。要评估这一点,您需要设置一个测试服务器并使用典型负载点击它以查看会发生什么。请注意,您可能需要从多台计算机上点击它以在服务器上施加实际负载,因为从一台计算机上命中它可能会因测试客户端计算机上的CPU核心数和其他资源而限制负载。

坦率地说,我只需要调整大小10000并调整工作线程数而不是队列大小。

答案 1 :(得分:2)

对磁盘的连续写入速度相当快(每秒容易20MB)。您可能最好不要将数据写入磁盘而不必担心内存需求,而不是将数据存储在RAM中。然后,您的客户可以从文件而不是RAM中读取数据。

要知道java对象的大小,可以使用任何java profiler。 YourKit是我的最爱。

我认为真正的问题不是队列的大小,而是当事情超出计划容量时你想要做的事情。 ArrayBlockingQueue将简单地阻塞你的线程,这可能是也可能不是正确的。您的选择通常是:

1)根据为此目的提交的内存阻塞线程(使用ArrayBlockingQueue) 2)将错误返回到“上面的层”并让该层决定做什么......可能会向客户端发送错误 3)你能丢掉一些数据吗...说很久以前就已经排队了。 4)一旦溢出RAM容量,就开始写入磁盘。

相关问题