| ▲ | marginalia_nu 2 days ago | |||||||
Object pooling still has its place, but like any optimization it needs to be based on benchmarks and shouldn't be done haphazardly. Blindly pooling objects will lead to regressions and resource contention more often than improvements. There are also middle ground options, like pooling objects but giving the pool a lifecycle that is tied to a request. | ||||||||
| ▲ | pron 2 days ago | parent [-] | |||||||
The problem is that 1. it's not easy to beat the JDK's GCs at memory management (assuming you've picked the right GC for your workload) especially as they keep getting better and better, and 2. how a pool behaves relative to the GC depends greatly on the GC algorithm (e.g. the same pool could help a bit with, say, Parallel GC, and hurt significantly with G1 or ZGC), and the different GC algorithms also tend to change significantly from release to release, so it's hard to write a good pool that can remain good both across different GCs and across different runtime versions. In particular, the JDK's GCs are heavily optimised for short-lived objects with high allocation rates. What you want to avoid is temporary data finding itself in the old gen. The newer GCs may dynamically size the young generation to match your program's natural meaning of "short lived", but the longer an object lives, the higher the chances it ends up in the old gen. You want only objects that stick around for a very long time (and have a low allocation rate) to end up in old gen. If you just write naive code, chances are things will work out well. Once you start being clever, you're taking a risk. So if you're willing to profile your program, with a workload that's representative of production workload (a microbenchmark is useless) on every runtime version and potentially change your "manual optimisation" every six months, you can try. But if not, the advice for the best performance over time is to rely on the platform and let it do its thing. The reason is that the JVM is continuously being optimised for "normal programs". If you're doing anything too clever, you may find that in a future release, your code is making things worse because the optimisations that target normal code don't help your code (or could even treat it as unusual and have it hit slow paths). I once spoke to a company that were very proud in getting something like a 10% improvement over naive code in Java 8, thanks to some hand optimisation they worked a lot on, only to discover that it caused a 15% regression compared to doing nothing special on JDK 11. | ||||||||
| ||||||||