我是新来的爪哇人。我是c++程序员,现在学习java已经2个月了。抱歉,我的泳池英语。
我有一个问题,如果它需要内存池或对象池的Akka演员模型。我认为,如果我从一个参与者发送一些消息给另一个参与者,我必须分配一些堆内存(就像新的一些字符串,或者一些新的BigInteger等等)。随着时间的推移,垃圾收集器将被启动(我不确定它是否会启动),这会使我的应用程序计算得很慢。
因此,我寻找使内存池和失败(Java不支持内存池)的方法。我可以制作对象池,但在其他项目中,我没有发现任何人使用对象池与演员(也在Akka主页)。
在akka主页上有关于这个主题的文件吗?请告诉我链接或告诉我问题的解决方案。
谢谢。
发布于 2017-05-18 08:51:24
使用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以及稍后您需要它的地方(在接收消息的参与者中)
YOURCLASS instanceName = queue.take();您可能需要编写一些代码来创建和管理池。但这是它的要旨。
发布于 2017-05-18 09:32:20
如果您可能会在多台计算机上使用Akka,则消息将在有线上序列化并发送到另一个实例。这意味着仅仅一个本地内存池是不够的。
虽然从技术上讲,您可以编写一个自定义JSerializer (参见doc 这里)实现,在反序列化这些消息后将本地消息存储在内存池中,但我觉得对大多数应用程序来说,这有点过分了(而且在地图中查找时间很容易导致性能恶化)。
是的,当GC启动时,应用程序在负载过重的情况下会有点滞后。但是在95%的场景中,特别是在Akka这样的性能框架下,GC不会成为您的瓶颈: IO会的。
我不是说你不该这么做。我是说,在你承担这个任务之前,考虑到它的非琐碎性,你应该在运行时用Kamon或其他Akka专用的监控解决方案来衡量GC对你应用程序的影响,并且只有在你确信它是值得的之后,你才能使用它。
发布于 2020-10-21 03:46:34
可以进行对象池,以最小化延迟的长尾(通过牺牲多线程环境中的中位数)。考虑使用适当的队列,例如来自JCTools、分发者或Agrona的队列。不要忘记使用存储对象中的多个状态( https://youtu.be/nhYIEqt-jvY (我能找到的最好的内容)通过可变状态进行状态交换)的约定规则。
同样,不要期望在使用这种稍微危险的技术的过程中有所改进。您将失去L1-L3缓存效率,并将礼貌的PCI与障碍。
切线(以获得低延迟技术):如果您想坚持使用Akka,或者使用自定义的反应模型,其中对象池被单线程使用,或者内存被复制,例如分发器的方法,您可以考虑一些延迟较低的GC实现。另一种选择是使用内存区域( Erlang的工作方式)。它会产生垃圾,但在形式上很容易被GC处理!
如果您使用非常低的延迟IO,并且是延迟的最大敌人--忘记遗留的TCP (在Infininiband上的RDMA)、交换机(通过操作系统调用和文件系统访问磁盘(使用RDMA )、忘记由同一个核心共享的中断,而不是将核心固定在真正的CPU核心(vs虚拟/超线程)或NUMA通信或消息之间,而不是一个接一个地为多个用户提供硬件多播(或更好的光开关),也不要忘记为JVM打开Epsilon GC;
https://stackoverflow.com/questions/44042507
复制相似问题