0

I a new in java. I'm c++ programmer and nowadays study java for 2 months. Sorry for my pool English.

I have a question that if it needs memory pool or object pool for Akka actor model. I think if i send some message from one actor to one of the other actors, i have to allocate some heap memory(just like new Some String, or new Some BigInteger and other more..) And times on, the garbage collector will be got started(I'm not sure if it would be started) and it makes my application calculate slowly.

So I search for the way to make the memory-pool and failed(Java not supported memory pool). And I Could Make the object pool but in others project i did not find anybody use the object-pool with actor(also in Akka Homepage).

Is there any documents bout this topic in the akka hompage? Plz tell me the link or tell me the solution of my question.

Thanks.

Kebron
  • 23
  • 4

3 Answers3

1

If, as it's likely you will, you are using Akka across multiple computers, messages are serialized on the wire and sent to the other instance. This means that simply a local memory pool won't suffice.

While it's technically possible that you write a custom JSerializer (see the doc here) implementation that stores local messages in a memory pool after deserializing them, I feel that's a bit of an overkill for most applications (and easy to cock-up and actually worsen performance with lookup times in the map)

Yes, when the GC kicks in, the app will lag a bit under heavy loads. But in 95% of the scenarios, especially under a performant framework like Akka, GC will not be your bottleneck: IO will.

I'm not saying you shouldn't do it. I'm saying that before you take on the task, given its non-triviality, you should measure the impact of GC on your app at runtime with things like Kamon or other Akka-specialized monitoring solutions, and only after you are sure it's worth it you can go for it.

Diego Martinoia
  • 4,592
  • 1
  • 17
  • 36
0

Using an ArrayBlockingQueue to hold a pool of your objects should help,

Here is the example code.

TO create a pool and insert an instance of pooled object in it.

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

and later where you need it (in your actor that receives message)

YOURCLASS instanceName = queue.take();

You might have to write some code around this to create and manage the pool. But this is the gist of it.

onkkno
  • 655
  • 6
  • 16
  • And what exactly guarantees that once you do queue.take() there hasn't been other actor's queue.put()'s ? – Diego Martinoia May 18 '17 at 09:33
  • Using proper technique to mediate access to the queue helps avoid races almost completely. refer [this Code review answer for possible implementations](https://codereview.stackexchange.com/a/87206) – onkkno May 19 '17 at 07:17
  • My point being: if you enforce a total ordering (like mediation) on the messages sent, then you lose the spirit of Akka to ensure the ordering only between the same destination-sender pair, at the cose of a lot of more performance than what the GC gives you – Diego Martinoia May 19 '17 at 08:53
  • I see where we differ. This doesn't seem to enforce any ordering on the messages sent. This is just a place where a bunch of pre-allocated objects are held to be used by his actor instead of doing a potentially expensive operation again and again. I really do understand now that this isnt in the spirit of Akka in the truest sense. – onkkno May 19 '17 at 10:51
0

One can do object pooling to minimise long tail of latency (by sacrifice of median in multythreaded environment). consider using appropriate queues e.g. from JCTools, Distruptor, or Agrona. Don't forget about rules of engagement for state exhange via mutable state using multiple thereads in stored objects - https://youtu.be/nhYIEqt-jvY (the best content I was able to find).

Again, don't expect to improve throughout using such slightly dangerous techniques. You will loose L1-L3 cache efficiency and will polite PCI with barriers.

Bit of tangent (to get sense of low latency technology): One may consider some GC implementation with lower latency if you want to stick with Akka, or use custom reactive model where object pool is used by single thread, or memory copied over e.g. Distrupptor's approach. Another alternative is using memory regions (the way Erlang VM works). It creates garbage, but in form easy to handle by GC!

If you go to very low latency IO and are the biggest enemy of latency - forget legacy TCP (vs RDMA over Infininiband), switches (over swichless), OS accessing disk via OS calls and file system (use RDMA), forget interrupts shared by same core, not pinned cores (and without spinning for input) to real CPU core (vs virtual/hyperthreads) or inter NUMA communication or messages one by one instead of hardware multicast (or better optical switch) for multiple consumers and don't forget turning Epsilon GC for JVM ;)

PranasB
  • 71
  • 4
  • Forgot to mention insane common practice of Actors granularity. Small in size does not mean one can create as many as one likes, most of memory will be polluted with object headers with valuable payload scatter across changing heap. Hardware is trying to get faster and software trying to make is slow. – PranasB Oct 21 '20 at 04:04