2

I've been stuck on my problem for quite some time. To give you a litte context, I have written a bot in Java and was planning to run it on a Raspberry Pi 3 Model A+ 24/7. To my surprise, when I tested the almost finished program, its memory consumption kept on rising indefinitely.

Soon I realised, I had to limit the memory usage which I looked up on several sites over the past couple months. Unfortunately, most of them are outdated (2013 and older) and the very few newer ones didn't cover the important changes which must have taken place because I'm not able to figure out why my issue is still occurring.

I've tried so many things over such a long period of time that I'm not sure if I'll be able to sum up all the things I've tried so far but will update this post if I remember some important details.

Please see the pictures of my last test with the following settings:

java -Xmx4m -Xms4m -Xss64k -XX:MaxMetaspaceSize=8m -jar bot.jar

enter image description here

enter image description here

As you see the memory was not limited and rose to the point where the process was killed shortly after. In some of my previous tests I used an empty while(true) loop because I don't think I have a memory leak in my program. Weirdly enough, the empty loop also increased the memory size very slowly but did also not decrease over time.

At this point I'm not sure if the JVM is even capable of having a specified memory limit. My code uses the Robot class to make screen captures and fire certain buttons in nested while loops which also remind the garbage collector to cue a collection with System.gc(). Do I also have to use the following argument for the JVM?

-XX:MaxDirectMemorySize

I'm really confused with all the changes on Java as well. I've tried a few different JDKs because I thought that might solve the problem. The last test was compiled with the JDK 14 and runs on Java 11. Do I need to configure something on the OS in order to limit the memory consumption?

Maybe you guys could also recommend me a profiler with which I can check what is even allocating the memory in order to figure out what needs to be limited via the arguments but I would definitely need some help because I have never worked with one before.

I appreciate any help on this topic! Please let me know if you need any additional information and I will do my best to follow up during the week.

devEnju
  • 207
  • 1
  • 9
  • 2
    Take a look at [this answer](https://stackoverflow.com/a/53624438/3448419), [Memory Footprint of a Java Process](https://vimeo.com/364039638) video, and [the post](https://shipilev.net/jvm/anatomy-quarks/12-native-memory-tracking/) about Native Memory Tracking. – apangin Aug 30 '20 at 21:37
  • Have you tried running it through a debugger? I had a similar problem, and found out it was threads hung up on the wait method which were not receiving the notify from the thread lock. – Cardinal System Aug 30 '20 at 22:34
  • Do you have a memory leak? – Thorbjørn Ravn Andersen Aug 30 '20 at 22:54
  • 2
    4 megabytes is not enough to run the jvm. I'm surprised it doesn't exit immediately with a memory allocation error - perhaps the memory limit is now validated and if it's less than some minimum it's ignored. Can you reproduce the issue with a more reasonable limit like 100 megabytes? – Joni Aug 31 '20 at 03:05
  • Thanks for all the suggestions. I limited the memory size of the JVM to 4mb because it always takes a few days till the process gets killed and because my program doesn't rely on a such a huge stack size. I will increase it to 128mb during the next test and will configure everything apangin said in his presentation. Really great work that was exactly what I was looking for but couldn't find it. A debugger didn't show any suspicious activity but it's also really hard to use it while the bot is running so I'll definitely check again. Again thank you so much! – devEnju Aug 31 '20 at 18:26

1 Answers1

1

Maybe you can use the following args : -XX:+PrintGCDetails -Xloggc:/tmp/jvm-gc.log. It will log gc details in /tmp/jvm-gc.log .

Or you can check the size of the runtime heap with the following command:

# get the pid
ps -aux | bot.jar

# show the heap info
jmap -heap <pid>

sheng yan
  • 136
  • 1
  • 10
  • Thanks for your recommendation on the logging! For my next test I'll definitely have some logs and I'm able to monitor the heap of the program. Hopefully I'll have some results by the end of tomorrow since it takes some time till the memory built up. – devEnju Aug 31 '20 at 18:31