Java 如何估计或计算ArrayBlockingQueue的大小

Java 如何估计或计算ArrayBlockingQueue的大小,java,multithreading,queue,Java,Multithreading,Queue,作为标题,在我的模块中,我有一个blockingqueue来传递我的数据。服务器可以生成的数据是大量的日志信息。为了避免影响服务器的性能,我编写了多线程客户端来使用这些数据并将它们持久化到数据缓存中。因为每分钟可以产生大量的数据,所以我很困惑应该初始化多少大小的队列。我知道我可以设置我的队列策略,如果产生更多的数据,我可以省略溢出部分。但是为了尽可能多地保存这些数据,我在队列中创建了多少大小 你能给我一些建议吗?据我所知,这与我的服务器JVM堆栈大小有关&我JVM中的单个日志数据???使其“尽可

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

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

使其“尽可能大”。例如,如果您同意它最多消耗1Gb内存,则将其大小分配为1Gb除以队列中对象的平均字节数

如果我必须选择一个“合理”的数字,我会从
10000
开始。原因是,如果它变得更大,那么将其变大不是一个好主意,也不会有多大帮助,因为显然日志记录需求超过了您的日志记录能力,所以是时候退出客户端了

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

  • 如果应用程序的活动有高低之分,那么较大的队列将有助于“平滑”服务器上的负载
  • 如果您的应用程序具有相对稳定的负载,则较小的队列是合适的,因为较大的队列只会延迟客户端被阻塞时的不可避免点-您最好将其变小,并投入更多资源(多几个日志线程)来消耗工作
还要注意,非常大的队列可能会影响垃圾收集对释放内存的响应,因为它每次运行时都必须遍历更大的堆(队列中的所有对象),从而增加CPU和内存的负载

您希望在不太影响吞吐量和响应能力的情况下,尽可能减小大小。要评估这一点,您需要设置一个测试服务器,并使用典型负载点击它,看看会发生什么。请注意,您可能需要从多台机器上点击它,以便在服务器上施加实际负载,因为从一台机器上点击它会限制负载,因为测试客户端机器上的CPU内核和其他资源的数量

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

使其“尽可能大”。例如,如果您同意它最多消耗1Gb内存,则将其大小分配为1Gb除以队列中对象的平均字节数

如果我必须选择一个“合理”的数字,我会从
10000
开始。原因是,如果它变得更大,那么将其变大不是一个好主意,也不会有多大帮助,因为显然日志记录需求超过了您的日志记录能力,所以是时候退出客户端了

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

  • 如果应用程序的活动有高低之分,那么较大的队列将有助于“平滑”服务器上的负载
  • 如果您的应用程序具有相对稳定的负载,则较小的队列是合适的,因为较大的队列只会延迟客户端被阻塞时的不可避免点-您最好将其变小,并投入更多资源(多几个日志线程)来消耗工作
还要注意,非常大的队列可能会影响垃圾收集对释放内存的响应,因为它每次运行时都必须遍历更大的堆(队列中的所有对象),从而增加CPU和内存的负载

您希望在不太影响吞吐量和响应能力的情况下,尽可能减小大小。要评估这一点,您需要设置一个测试服务器,并使用典型负载点击它,看看会发生什么。请注意,您可能需要从多台机器上点击它,以便在服务器上施加实际负载,因为从一台机器上点击它会限制负载,因为测试客户端机器上的CPU内核和其他资源的数量


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

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

要知道java对象的大小,可以使用任何java探查器。你的工具包是我最喜欢的

我认为真正的问题不在于队列的大小,而在于当事情超出您的计划容量时您想做什么。ArrayBlockingQueue只会阻塞线程,这可能是正确的,也可能不是正确的。您的选择通常包括:

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

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

要知道java对象的大小,可以使用任何java探查器。你的工具包是我最喜欢的

我认为真正的问题不在于队列的大小,而在于当事情超出计划的capa时你想做什么