Java Akka参与者消息需要内存池

Java Akka参与者消息需要内存池,java,akka,actor,object-pooling,memory-pool,Java,Akka,Actor,Object Pooling,Memory Pool,我用java写了一篇新文章。我是C++程序员,现在学习java已经2个月了。 对不起,我的英语太差了 我有一个问题,如果Akka演员模型需要内存池或对象池。我认为,如果我从一个参与者向另一个参与者发送一些消息,我必须分配一些堆内存(就像new some String,或new some biginger和其他更多…),并且随着时间的推移,垃圾收集器将启动(我不确定它是否会启动),这会使我的应用程序计算速度变慢 因此,我搜索创建内存池的方法失败了(Java不支持内存池)。我可以创建对象池,但在其他

我用java写了一篇新文章。我是C++程序员,现在学习java已经2个月了。 对不起,我的英语太差了

我有一个问题,如果Akka演员模型需要内存池或对象池。我认为,如果我从一个参与者向另一个参与者发送一些消息,我必须分配一些堆内存(就像new some String,或new some biginger和其他更多…),并且随着时间的推移,垃圾收集器将启动(我不确定它是否会启动),这会使我的应用程序计算速度变慢

因此,我搜索创建内存池的方法失败了(Java不支持内存池)。我可以创建对象池,但在其他项目中,我没有发现任何人将对象池与actor一起使用(也在Akka主页中)

《阿卡庄园》里有关于这个话题的文件吗?请告诉我链接或告诉我问题的解决方案


谢谢。

使用ArrayBlockingQueue保存对象池应该会有所帮助

下面是示例代码

创建池并在其中插入池对象的实例

BlockingQueue<YOURCLASS> queue = new ArrayBlockingQueue<YOURCLASS>(256);//Adjust 256 to your desired count. ArrayBlockingQueues size cannot be adjusted once it is initialized.


queue.put(YOUROBJ); //This should be in your code that instanciates the pool
您可能需要为此编写一些代码来创建和管理池。
但这就是它的要点。

如果您可能在多台计算机上使用Akka,则消息会在线路上序列化并发送到另一个实例。这意味着仅仅一个本地内存池是不够的

虽然从技术上讲,您可以编写一个定制的JSerializer(参见文档)实现,在反序列化本地消息后将其存储在内存池中,但我觉得对于大多数应用程序来说,这有点过分(而且很容易出错,实际上会随着映射中的查找时间而降低性能)

是的,当GC启动时,应用程序在重载下会有一点滞后。但在95%的场景中,特别是在Akka这样的性能框架下,GC不会成为您的瓶颈:IO会


我不是说你不应该这么做。我的意思是,在你承担这项任务之前,考虑到它的非平凡性,你应该在运行时用Kamon或其他Akka专门的监控解决方案来衡量GC对你的应用程序的影响,并且只有在你确信它是值得的之后,你才能去做它。

你可以通过对象池来最小化延迟的长尾(通过在多线程环境中牺牲中间值),考虑使用适当的队列,例如从JCoToice、Debug或AgNONA等。不要忘记使用存储对象中的多个对象通过可变状态来访问状态Exchange的规则——(我能找到的最佳内容)。 再说一次,不要指望通过使用这种稍微危险的技术来提高性能。这样会降低一级到三级缓存的效率,并且会增加障碍

切点(以了解低延迟技术): 如果你想坚持AKKA,或者使用定制的反应模型,其中单池使用对象池,或者通过Distoppor的方法复制内存,则可以考虑一些较低延迟的GC实现。 另一种选择是使用内存区域(ErlangVM的工作方式)。它创建垃圾,但其形式易于GC处理


如果您使用的是非常低的延迟IO,并且是延迟的最大敌人-忘记传统TCP(与Infininiband上的RDMA相比)、交换机(与无开关设备相比)、操作系统通过操作系统调用和文件系统访问磁盘(使用RDMA)、忘记由同一个内核共享的中断,而不是固定内核(并且不旋转输入)到真正的CPU内核(与虚拟/超线程相比)或者一个接一个的NUMA间通信或消息,而不是针对多个使用者的硬件多播(或更好的光交换机),并且不要忘记为JVM启用Epsilon GC;)

以及什么可以确切地保证,一旦执行queue.take()操作,就不会出现其他参与者的队列。put()使用适当的技术调解对队列的访问有助于几乎完全避免竞争。请参考我的观点:如果您对发送的消息强制执行总排序(如中介),那么您就失去了Akka的精神,无法确保只在同一个目标-发送方对之间进行排序,因为它的性能要比GC提供的性能好得多。我知道我们的不同之处。这似乎没有对发送的消息执行任何排序。这只是一个地方,在这里,一堆预先分配的对象被保存起来供他的参与者使用,而不是一次又一次地执行一个潜在的昂贵操作。我现在真的明白了,这并不是真正意义上的阿克卡精神。忘了提到演员们疯狂的惯例。大小小并不意味着可以创建任意数量的对象,大多数内存将被对象头污染,有价值的负载分散在不断变化的堆中。硬件正试图变得更快,而软件正试图变得更慢。
YOURCLASS instanceName = queue.take();