英文:
How do I properly limit JVM's memory usage?
问题
我在解决我的问题上卡了很长一段时间。为了给你一点背景,我用Java写了一个机器人程序,并计划在树莓派3模型A+上全天候运行它。令我惊讶的是,当我测试几乎完成的程序时,它的内存消耗不断地无限增长。
不久后我意识到,我必须限制内存使用量,我在过去的几个月里在几个网站上查找了相关信息。不幸的是,其中大多数已经过时(2013年及更早),而为数很少的更新内容也没有涵盖重要的更改,这些更改可能已经发生,因为我无法弄清楚为什么我的问题仍在发生。
我已经尝试了很多方法,时间如此之长,以至于我不确定是否能够总结出我迄今为止所尝试的所有事情,但如果我记起一些重要的细节,我会更新这篇帖子的。
请查看我上次测试的图片,使用了以下设置:
java -Xmx4m -Xms4m -Xss64k -XX:MaxMetaspaceSize=8m -jar bot.jar
正如你所见,内存没有被限制,增长到一定点后进程就被迅速终止。在我之前的一些测试中,我使用了一个空的while(true)
循环,因为我认为我的程序没有内存泄漏。令人奇怪的是,这个空循环的内存使用量也很慢地增加,但也不会随着时间的推移而减少。
在这一点上,我不确定JVM是否能够有指定的内存限制。我的代码使用Robot类进行屏幕捕捉,并在嵌套的while循环中触发特定的按钮,这也会提醒垃圾收集器进行收集,使用System.gc()
。我还需要为JVM使用以下参数吗?
-XX:MaxDirectMemorySize
我对Java上的所有变化感到非常困惑。我尝试过几种不同的JDK,因为我认为这可能会解决问题。最后一次测试是使用JDK 14编译的,在Java 11上运行。我需要在操作系统上进行一些配置以限制内存消耗吗?
也许你们可以推荐一个性能分析工具,我可以用它来检查到底是什么在分配内存,以便弄清楚需要通过参数来限制什么,但我肯定需要一些帮助,因为我以前从未使用过这样的工具。
非常感谢关于这个主题的任何帮助!如果你们需要任何额外的信息,请告诉我,我会尽量在本周内跟进。
英文:
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
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.
答案1
得分: 1
也许你可以使用以下参数:-XX:+PrintGCDetails -Xloggc:/tmp/jvm-gc.log
。它会将GC详细信息记录在/tmp/jvm-gc.log中。
或者你可以使用以下命令来检查运行时堆的大小:
# 获取进程ID
ps -aux | bot.jar
# 显示堆信息
jmap -heap <pid>
英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论