我正在运行用Java或Scala编写的现有程序。这些程序由不同的作者编写,用于非常不同的目的,因此将它们集成到一个大型程序中是不可行的。当在具有许多核心(例如32个)和大量RAM(例如200G)的节点上启动任何这些java程序时,每个程序都尝试获取尽可能多的资源,以至于节点减速停止并且没有有用的计算完成了。例如,在不同数据集上运行32个Beagle实例会导致32个jvms,每个jvms尝试使用32个内核和大部分内存。 (Beagle没有配置显式多线程,默认为nthreads=1
。)
那么如何配置jvm的行为更像传统程序,它只使用尽可能多的内存和CPU ......
我知道以下标志,但还有其他标志需要考虑吗?
-Xmx limits maximum memory
-XX:+UseSerialGC disables multithreaded garbage collection
jvm真的可以是单线程吗?
此外,相当轻量级的Java程序都试图在具有200G RAM的节点上使用至少30G的RAM,而它们实际上只需要<1G的RAM。我设置-Xmx1G
并且这些程序运行没有错误或明显的性能下降;事实上,启动时间要快得多。
是否有比在内存上设置硬上限更优雅的解决方案?如果我将-Xmx
设置得太低,程序就会崩溃。如果我将它设置得太高,就会浪费资源。使用由细心的作者编写的用C ++编写的程序,我不需要调整这些东西。 C ++程序的内存使用量通常可以根据输入数据大小进行可预测的扩展。
为什么jvm可以默认使用它实际需要的数量?
除nice
和ulimit
之外,还有更好的解决方案吗?
nice +10 java
会遇到麻烦。
ulimit java
会导致jvm抛出拟合。
我在没有root访问权限的环境中工作。我不是在Linux服务器上工作而不是在Android上工作。
答案 0 :(得分:1)
-XX:-UseSerialGC
禁用串行GC,这与您想要的相反。
我在没有root访问权限的环境中工作。
如果使用用户命名空间编译内核,则可以使用unshare
输入新的用户命名空间,然后在该命名空间内使用 cgroups 来限制资源。
答案 1 :(得分:1)
jvm真的可以是单线程吗?
不,当它可以同时运行时就可以了。您可以使用taskset将JCVM限制为只有一个CPU字节,如果执行此操作,它将执行得非常糟糕,因为它需要多个CPU。
是否有比在内存上设置硬上限更优雅的解决方案?
我会尽力确定你的意思。
为什么jvm能够尽可能多地使用它?
它确实使用了所需的CPU和内存。
好的+10 java在新进程不断启动时会遇到麻烦
启动新的JVM可能会产生远远超过收益的开销。如果你想节省CPU,我会尽可能少地启动JVM。