2 years ago
Attached you see the RAM usage graph of my project. I am running a discord bot with a Java Spring Boot application, and on my local device, the app eventually uses <200 mb of RAM, but on railway, the ram usage continues to increase. I found a StackOverflow post that tackles a similar issue, but updating my Dockerfile with the runtime flags did not deliver noticeable changes (see the last deployed commit, compared to the rest). Ideally, I don't have to manually call the GC, although it is an option available to me.
Does anyone have any recommendations for getting my Java app to release unused RAM memory?
23 Replies
2 years ago
1a73e8f4-a61d-4a67-9bd7-3539b677698b
2 years ago
that's more so looking like a memory leak to me
2 years ago
If it was, then i'd be able to reproduce that locally, no?
2 years ago
do you build from the dockerfile file and run the resulting image ?
2 years ago
Yes
2 years ago
well it's not like railway is making up metrics
2 years ago
According to stack it's because java isnt by default configured for containers, which is why i asked here if people had knowhow of how i should configure the dockerfile
2 years ago
My apologies if I gave you the wrong answer to this question. I mean that Railway is running from the Dockerfile, and my local machine is the bare Java app. Local machine has less ram usage then the deployment on railway.
The attached stackoverflow post claims that java won't unclaim heap space the same way if it's running in a container. There were runtime flags i could add to the dockerfile that'd supposedly fix this, but this did not have the desired effect
2 years ago
what effect did it have, if any
2 years ago
Practically none if it didnt make it worse
2 years ago
Are you sure the flags were taken into account when deploying?
2 years ago
How can I verify that?
2 years ago
Logs
2 years ago
A quick search doesn't give me any hits for the flags, so i guess they're not being considered
2 years ago
I'll play with those when i get back home and see if i can get it working. Probably misusing them
2 years ago
I am the most smoothbrained ape on this planet
2 years ago
Flags go before the -jar flag 🤦
2 years ago
Did it help your heap usage?
2 years ago
Going to redeploy now and see if it helps
2 years ago
I've had her run for a bit and it definitely looks like it helped. RAM usage continues to grow but does so much slower
2 years ago
I'm trying if ShenandoahGC helps more. It looks promising so far
2 years ago
It looks like shenandoahGC has given my app a healthier ram graph. Thank you all for your help!
6 months ago
Apologies for necroposting my own thread, but after ~2 years I've found the root cause of the issue.
The good news? There's no memory leak!
The bad news? netty was responsible for ~50% of my heap usage (because of - get this - it's own network buffer reserving space it did not use), and ShenandoahGC wasn't quite built to suit my needs, which caused the (claimed) heap memory to grow ever so slowly. (I swapped to G1GC which does a great job of keeping the heap as big as it needs to be. In defense of ShenandoahGC: it was still leagues better then whatever the default GC was doing)
What's also growing slowly is my Metaspace size, the root cause of which is most certainly also my dependencies (there's about 18 - 19.000 classes loaded, of which i probably haven't even written 100.).
Let this be a lesson and a warning for other devs like me. Spring is convenient, but also quite taxing on resources. You should have a proper think about if you need it before committing to the framework, and then also what parts of the framework you need. In my case I have a dependency on spring-web which spins up a Tomcat server that I simply do not use (among other things), all just so I can have some mediocre syntax sugar for making HTTP requests for a single class.
Java has a pretty decent (albeit slightly cumbersome) HTTP API built-in, which was more then enough to suit my needs.