It's not rocket science honestly. Mostly any Java performance guide will tell you how.
Allocate either locally on the stack or allocate for the life of the process so it never gets GC'd.
Of course, spend time profiling to make sure you got it. Figure out your redeployment cadence and that sets the ceiling for how much data can be an exception to these rules.
(e.g. if you redeploy nightly then it's fine to grow the memory consumption as long as you don't hit full GC in less than 24hrs.)
Allocate either locally on the stack or allocate for the life of the process so it never gets GC'd.
Of course, spend time profiling to make sure you got it. Figure out your redeployment cadence and that sets the ceiling for how much data can be an exception to these rules.
(e.g. if you redeploy nightly then it's fine to grow the memory consumption as long as you don't hit full GC in less than 24hrs.)
In a nutshell that's it.