限制Play框架全局的Java堆空间

33

我有一个非常老的Linux系统,并安装了Java和Play框架。当我运行Java时,会出现以下错误:

java -version
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

因此,我在application.conf中限制了Java堆空间:

jvm.memory=-Xmx256M -Xms256M

有了这个设置,我可以运行play test、play run等操作……

但我无法运行:

play dependencies 
~        _            _ 
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/   
~
~ play! 1.2.1, http://www.playframework.org
~
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

是否有全局配置文件或环境变量可以在Play框架中全局限制Java堆空间?

更新: 以下内容也不起作用:

play dependencies -Xmx256M -Xms256M
~        _            _ 
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/   
~
~ play! 1.2.1, http://www.playframework.org
~
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
更新2:

内存:

ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
pending signals                 (-i) 1024
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 38912
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

限制:

cat /proc/meminfo 
MemTotal:      4139312 kB
MemFree:        332988 kB
Buffers:        105252 kB
Cached:        1705644 kB
SwapCached:          4 kB
Active:        2566216 kB
Inactive:       625032 kB
HighTotal:      786432 kB
HighFree:         1728 kB
LowTotal:      3352880 kB
LowFree:        331260 kB
SwapTotal:     4192956 kB
SwapFree:      4168224 kB
Dirty:             368 kB
Writeback:           0 kB
Mapped:        1672180 kB
Slab:           570864 kB
CommitLimit:   6262612 kB
Committed_AS:  4075144 kB
PageTables:      19884 kB
VmallocTotal:   303096 kB
VmallocUsed:     10400 kB
VmallocChunk:   292648 kB

BR,

Rene


请注意,-Xmx/-Xms表示使用的堆内存量,实际使用的总内存量将远远高于此。 - kritzikratzi
9个回答

24

播放似乎没有使用jvm.memory设置来处理依赖项甚至测试命令。强制其使用特定的JVM设置的一种方法是使用_JAVA_OPTIONS。

例如:

export _JAVA_OPTIONS="-Xms800m -Xmx1500m -XX:PermSize=64m -XX:MaxPermSize=256m"
play test
或者
play deps

你应该看到

~        _            _ 
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/   
~
~ play! 1.2.3, http://www.playframework.org
~ framework ID is test
~
~ Running in test mode
~ Ctrl+C to stop
~ 
Picked up _JAVA_OPTIONS: -Xms800m -Xmx1500m -XX:PermSize=64m -XX:MaxPermSize=256m
Listening for transport dt_socket at address: 8000

请注意,这将应用这些设置到在设置了_JAVA_OPTIONS的终端上运行的所有Java程序。


2
在Play 1.2.4中,环境变量似乎是JAVA_OPTS。 - itsadok
1
@itsadok:实际上,这似乎更像是Java运行时的问题,而不是Play特定的问题。如果您设置了_JAVA_OPTIONS并运行“java-version”,则会看到设置被拾取。 - Ayush Gupta
我猜我们在谈论两种完全不同的机制。我是指的是这个 - itsadok
Play 2.2.0怎么样? - Kevin Meredith
设置这个会给我“未检测到Java安装。 请访问http://www.java.com/getjava/并下载”错误。 - Daniel

19
在更多的谷歌搜索后,我发现了这个讨论:点击此处。问题是,我的Linux系统运行在一个openvz容器中:
Java抱怨的原因是,在启动时,它看到机器拥有超过2GB的RAM,所以它会以服务器模式启动,尝试分配所有内存,但由于它在VPS内部,这导致了失败。
我可以通过修改/usr/java/jdk1.6.0_26/jre/lib/i386/jvm.cfg来解决java启动问题:
-client IF_SERVER_CLASS -server
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR

to:

#-client IF_SERVER_CLASS -server
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR

现在我能运行任何play命令。也许这对于其他遇到容器虚拟化相关问题的人有所帮助。

祝好,Rene


1
哇,你是怎么发现的?你救了我的命 :) - Salil
我正在使用VPS,但这并没有解决我的问题。:( - Jay Q.
+1 我正在使用 Citrix 系统,所以这肯定会对我有所帮助! - Mr. Developerdude
较新的版本(在我的情况下是x64上的1.7.0_40)似乎不再具有客户端JVM。我想可能只能使用服务器了。真糟糕。 - Dominykas Mostauskis

12

通常情况下,当您使用以下模式调用play时,可以指定Java命令行参数。

play run <appname> -Xmx256M -Xms256M

然而,查看play run命令和play dependencies命令的Python代码时,它们以不同的方式调用Java。

play dependencies命令在没有通过-X命令(出于某种原因,它会经过-D命令)的情况下调用Java。因此,除了编辑framework/pym/play/commands文件夹中的deps.py文件并将-Xmx和-Xms设置硬编码到该文件中外,您无法做任何事情。

这不是长期的解决方案,我建议您在Play上提出一个票据,允许从命令行或application.conf中读取这些设置,但目前,我认为这是您唯一的选择。


帖子已更新。我已经查看了Python代码,现在完全明白你的问题了。 - Codemwnci
谢谢,我已经硬编码并创建了一个工单。进化也有同样的问题 :-( - reen

6
我在我的Fedora笔记本电脑上运行Play 2.0时,启动交互式shell时遇到了这个问题。我发现构建脚本默认将内存值设置为相当高的值。
为了解决这个问题,我不得不编辑$play_dir/framework/build脚本并手动更改值,在脚本末尾执行以下操作来启动:
java ${DEBUG_PARAM} -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M ...

只需相应地更改 -Xmx/-Xms 值(可能还包括 permgen)即可。

3
在Play 2.2和Java 7中,这是我使用的方法。
$ target/universal/stage/bin/foo -mem 256 -J-server

关于-mem的详细信息,请参阅:

$ target/universal/stage/bin/foo -h

3
你的电脑没有足够的RAM来运行Java。Java需要至少64MB RAM。
请注意,你不能通过指定“-Xms”来向你的计算机添加免费内存:Java无法向你的主板添加内存模块。“-Xms”只是告诉Java要占用多少可用的RAM。如果这失败了(当Java尝试分配时操作系统返回错误),你就会得到上面的错误。
我猜测可能是没有交换空间。查看“cat /proc/meminfo”的输出。或者你设置了限制每个进程可以分配多少内存的“ulimit”(尝试使用“ulimit -a”进行检查)。

请参见更新2。仍有交换空间可用,几乎使用了1 GB的内存缓存。 - reen
这真的很奇怪。尝试调用 java -version -Xmx32M(仅使用32MB甚至更少)。只要您无法启动 java 本身,play 就无法工作。 - Aaron Digulla
看我的回答。问题是Java在容器中运行。 - reen

2
似乎您运行的play命令实际上是一个Python脚本,它调用其他Play Framework Python模块,最终作为子进程调用java命令。
查看运行dependencies命令的代码的源代码,似乎没有加载环境变量或任何其他指定最大堆大小作为-Xmx参数的逻辑。换句话说,从Play中调用JVM的Python代码在此脚本中没有办法从默认值指定最大堆大小。

0

我遇到了同样的问题。尝试将--XX:MaxHeapSize增加到更高的分配量。这是我的配置在path/to/framework/build中

java -Xms512M -Xmx1300M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -XX:MaxHeapSize=512m...

0

Play不识别-XX选项。请改用-DX。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接