简体   繁体   English

如何正确限制 JVM 的内存使用量?

[英]How do I properly limit JVM's memory usage?

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.为了给您提供一些上下文,我用 Java 编写了一个机器人,并计划在 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.不幸的是,它们中的大多数已经过时(2013 年及更早),并且很少有较新的版本没有涵盖必须发生的重要更改,因为我无法弄清楚为什么我的问题仍在发生。

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.在我之前的一些测试中,我使用了一个空的 while(true) 循环,因为我认为我的程序中没有内存泄漏。 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.在这一点上,我不确定 JVM 是否能够具有指定的内存限制。 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().我的代码使用 Robot 类来制作屏幕截图并触发嵌套 while 循环中的某些按钮,这也提醒垃圾收集器使用 System.gc() 提示收集。 Do I also have to use the following argument for the JVM?我是否还必须对 JVM 使用以下参数?

-XX:MaxDirectMemorySize

I'm really confused with all the changes on Java as well.我也对 Java 的所有变化感到困惑。 I've tried a few different JDKs because I thought that might solve the problem.我尝试了几种不同的 JDK,因为我认为这可能会解决问题。 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?最后一个测试是用 JDK 14 编译并在 Java 11 上运行的。我是否需要在操作系统上配置一些东西来限制内存消耗?

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.如果您需要任何其他信息,请告诉我,我将尽我所能在一周内跟进。

Maybe you can use the following args : -XX:+PrintGCDetails -Xloggc:/tmp/jvm-gc.log .也许您可以使用以下参数: -XX:+PrintGCDetails -Xloggc:/tmp/jvm-gc.log It will log gc details in /tmp/jvm-gc.log .它将在 /tmp/jvm-gc.log 中记录 gc 详细信息。

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM