我是一个新的java。我是一个c++程序员,现在学习java 2个月。对不起,我的池英语。
我有一个问题,如果它需要内存池或对象池的Akka演员模型。我认为,如果我发送一些消息从一个演员到其他演员之一,我必须分配一些堆内存(就像新的一些字符串,或新的一些大整数和其他更多..)和时间,垃圾收集器将得到启动(我不知道它是否会启动),它使我的应用程序计算缓慢。
因此,我寻找的方式,使内存池和失败(Java不支持内存池).我可以使对象池,但在其他项目中,我没有发现任何人使用对象池与演员(也在Akka主页).
在akka的主页上有关于这个主题的文档吗?请告诉我链接或者告诉我问题的解决方案。
- 谢谢-谢谢
3条答案
按热度按时间2cmtqfgy1#
如果您在多台计算机上使用Akka,消息将在网络上串行化并发送到其他示例,这意味着仅仅使用本地内存池是不够的。
虽然从技术上讲,您可以编写一个自定义的JSerializer(请参阅此处的文档)实现,在反序列化本地消息之后将其存储在内存池中,但我觉得这对大多数应用程序来说有点大材小用(而且很容易出错,实际上会因为Map中的查找时间而降低性能)
是的,当GC开始工作时,应用程序在重负载下会有一点延迟。但是在95%的场景中,特别是在Akka这样的高性能框架下,GC不会成为瓶颈:伊奥会的。
我不是说你不应该这么做,我是说,在你承担这项任务之前,考虑到它的重要性,你应该测量GC在运行时对你的应用的影响,比如Kamon或其他Akka专门的监控解决方案,只有在你确定它值得你去做之后,你才可以去做。
ckx4rj1h2#
使用ArrayBlockingQueue来保存对象池应该会有所帮助,
下面是示例代码。
创建一个池并在其中插入一个池对象示例。
然后在需要的地方(在接收消息的执行元中)
您可能需要编写一些代码来创建和管理池,但这是要点。
fd3cxomn3#
可以使用对象池来最小化延迟的长尾(通过牺牲多线程环境中的中值)。考虑使用适当的队列,例如来自JCTools、Distruptor或Agrona的队列。不要忘记通过可变状态使用存储对象中的多个读取进行状态交换的参与规则-https://youtu.be/nhYIEqt-jvY(我能找到的最好的内容)。
同样,不要指望使用这种稍微危险的技术来提高整体性能。你会失去L1-L3缓存的效率,并会用障碍来礼貌PCI。
切线位(了解低延迟技术):如果你想坚持使用Akka,你可以考虑一些延迟更低的GC实现,或者使用自定义的React式模型,其中对象池由单个线程使用,或者通过例如Distrupptor的方法复制内存。另一种选择是使用内存区域(Erlang VM的工作方式)。它会产生垃圾,但形式上很容易被GC处理!
如果您采用极低延迟的IO,并且您是延迟的最大敌人-请忘记传统TCP(相对于Infiniband上的RDMA)、交换机(通过无交换机),操作系统通过操作系统调用和文件系统访问磁盘(使用RDMA),忽略由相同核心共享中断,非固定核心(无需旋转输入)到真实的CPU内核(相对于虚拟/超线程)或NUMA间通信或消息,而不是硬件多播(或更好的光学开关),用于多个消费者,不要忘记将Epsilon GC用于JVM ;)