I think Java tends to grow memory usage up to a point, rather than to try and release it at the cost of performance. That doesn't mean it would not be able to run on a machine with lower memory. It could run more expensive GC if it was needed
Currently I can't run my integration tests on my work laptop because they spin up a bunch of "micro" services, so I run out of ram and need to reboot.
The memory that Java "doesn't require" really adds up.
So in my above scenario, I could indeed run the app with a -Xmx32M and yet the application was still using 200-300MB of resident memory (RSS) due to offheap usage.
-XX:NativeMemoryTracking=summary
jcmd <pid> VM.native_memory summary
I have a micronaut app that uses around 350MB which is almost entirely JVM overhead.
I used it initially for a small project (hobby-tier) and was shocked to find it was using 200-300MB of offheap (or something in that range). To where my poor 1GB RAM digital ocean VPS was 20-30% just random Spring offheap crap.
I ported my handlers from Spring to just using netty and their provided HTTP codecs (and I wrote my own http router implementation which was fun but also wish there was an easy one to just use, I didn't see anything I liked when I looked) and suddenly offheap was ~0 and I could've easily crammed 100 of these into this tiny VPS. (Not that I planned to, but I did want to use this VPS for other things too).
I know "300MB offheap" is not something Spring will care about when they're probably normally running on giant ec2 instances, but for my case, while I would've liked to use the "django/rails but for java"-type tool, it did actually end up being too heavy in the most-constrained vector of cloud hosting (RAM).