我是java的新手。我是c ++程序员,现在研究java 2个月。 对不起我的游泳池英语。
我有一个问题,如果它需要Akka actor模型的内存池或对象池。我想如果我从一个演员发送一些消息到其他演员之一,我必须分配一些堆内存(就像新的一些字符串,或新的一些BigInteger和其他更多..)和时间,垃圾收集器将是开始了(我不确定它是否会启动)并且它使我的应用程序计算缓慢。
所以我搜索了使内存池失败的方法(Java不支持的内存池)。我可以创建对象池但在其他项目中我没有发现任何人使用带有actor的对象池(也在Akka主页中)。
在akka hompage中是否有关于此主题的文档? Plz告诉我链接或告诉我我的问题的解决方案。
感谢。
答案 0 :(得分:1)
如果您可能会在多台计算机上使用Akka,则会在线路上序列化消息并将其发送到另一个实例。这意味着只需一个本地内存池就不够了。
虽然在技术上可以编写一个自定义JSerializer(请参阅doc here)实现,在反序列化后将本地消息存储在内存池中,但我觉得这对大多数应用程序来说有点过分(并且很容易)通过地图中的查找时间进行翘起并实际上恶化了性能
是的,当GC启动时,应用程序将在重负载下滞后一点。但是在95%的场景中,特别是在像Akka这样的高性能框架下,GC不会成为你的瓶颈:IO会。
我不是说你不应该这样做。我说在你完成任务之前,考虑到它的重要性,你应该在运行时衡量 GC对你的应用程序的影响,如Kamon或其他Akka专业监控解决方案,以及只有在你确定它值得之后,你才能去做。
答案 1 :(得分:0)
使用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();
您可能需要编写一些代码来创建和管理池。 但这是它的要点。
答案 2 :(得分:0)
可以进行对象池化以最大程度地减少等待时间(通过在多线程环境中牺牲中间值)。考虑使用适当的队列,例如来自JCTools,Distruptor或Agrona。别忘了使用存储对象中的多个reads-https://youtu.be/nhYIEqt-jvY(我能找到的最好的内容)来通过可变状态进行状态交换的参与规则。
同样,不要指望通过使用这种稍有危险的技术会有所改善。您将失去L1-L3缓存的效率,并且礼貌地使用PCI。
一些切线(以了解低延迟技术): 如果您想坚持使用Akka,或者使用自定义反应模型(其中对象池由单线程使用)或通过例如复制的内存来使用,则可以考虑使用一些具有较低延迟的GC实现。 Distrupptor的方法。 另一种选择是使用内存区域(Erlang VM的工作方式)。它会创建垃圾,但是形式容易被GC处理!
如果您进入非常低的延迟IO并且是延迟的最大敌人-忘记旧式TCP(与Infininiband上的RDMA相比),交换机(无三明治),通过OS调用和文件系统访问磁盘(使用RDMA)的OS,忘记由同一个内核共享的中断,而不是固定内核(不进行输入旋转)到真正的CPU内核(与虚拟/超线程)或NUMA内部通信或消息,而不是针对多个使用者和硬件的多播(而不是硬件多播)(或更好的光开关)别忘了为JVM启用Epsilon GC;)