虚拟服务器上的 Tomcat:由于 44 GB Ram 不够,JVM 无法启动?

虚拟服务器上的 Tomcat:由于 44 GB Ram 不够,JVM 无法启动?

我租了一个虚拟机,运行的是 Ubuntu 9.04。我安装了 SUN JDK 6.0 (通过 apt-get) 和 Tomcat 6.0.18 (通过解压)。

Java 的常见问题(部分解决)

起初,由于内存问题,无法运行 JVM。即使是java -version

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

我发现,尽管free报告了 44 GB 的可用内存,但我只能使用其中的一小部分,大约每次分配 284 MB。运行java -Xms10m -Xmx256m -version正常,但我不想更改每个调用 java 的脚本。

我还阅读了有关JAVA_OPTS环境变量的信息,许多应用程序都支持该变量。我已将其设置为"-Xms10m -Xmx256m"

Tomcat 问题

tomcat 启动脚本catalina.sh也使用了JAVA_OPTS。但即便如此,我仍然会收到上面提到的三行错误,可在中读取logs/catalina.out。我知道使用了 JAVA_OPTS,因为当我将无意义的内容放入该变量时,我会在中看到后果logs/catalina.out

看起来 Tomcat 还想启动 javac,而 javac 需要以-Jlike为前缀的选项-J-Xms10m -J-Xmx256m。但我不确定这是否与问题有关,因为除了这三行之外没有其他输出。

我正在通过 启动 Tomcat,bin/startup.sh然后依次调用bin/catalina.sh。我知道也可以通过 启动它jsrv,但我无法做到这一点,因为 的 make / configure 过程jsrv也需要调用 ,javac这会失败并出现上面提到的众所周知的三行错误消息。

现在我对两种可能的解决方案感兴趣:

  • 我怎样才能让 Java只是工作在我的虚拟主机上,无论谁呼叫javajavac无论他如何呼叫?
  • 如果这是不可能的,我该如何调整 Tomcat 以使其运行?

PS:请注意,我只能控制虚拟机,但无法控制周围的物理机器,而且对其了解有限。

备注:抱歉,这个问题的标题太菜鸟了,但我觉得原来的标题写得很好,没有吸引足够的读者,所以我觉得这个标题可能会有帮助 ;) 它确实有帮助,因为我在第一个小时内没有获得任何浏览量,但在更改后的一个小时内获得了 8 次浏览量。奇怪的世界。

编辑:这是输出ulimit -a

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

答案1

javac通常会产生一个单独的进程应该属于不同的流程规则。

-J选项用于通过包装器/启动器将参数传递给 JVM,我还没有在 Tomcat 上看到过这个。

找出 -Xmx 的来源:

find /your/install/dir/with/tomcat |xargs grep '-Xmx'

答案2

尝试ulimit -v unlimited在启动 tomcat 之前运行。如果可行,您可以将其添加到一个或两个启动脚本中,或者添加到/etc/profile~/.bashrc其他某个 shell 配置文件脚本中。

答案3

由于没有其他选择,我尝试了一种肮脏的黑客方法:用 shell 脚本替换javajavac,以确保传递正确的参数并允许我查看准确的参数列表。由于这已经是一种非常具体的解决方案的尝试,而不是问题的一部分,所以我想把它放到答案中。

我搜索了java文件系统中的所有出现。结果太多了,因为我的机器上有多个 JRE 和 JDK。即使删除了所有版本,只留下一个版本,仍然有很多。我过去常常find / -name "java" |xargs file找出哪个是真实的一。它告诉我:

/var/lib/dpkg/alternatives/java:               ASCII text
/etc/alternatives/java:                        symbolic link to `/usr/lib/jvm/java-6-sun/jre/bin/java'
/usr/share/java:                               directory
/usr/lib/jvm/java-6-sun-1.6.0.16/bin/java:     symbolic link to `../jre/bin/java'
/usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.0, not stripped
/usr/bin/java:                                 symbolic link to `/etc/alternatives/java'

所以我知道那/usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java是可执行文件。我将其重命名,javaexec并将一个 shell 脚本放在其旧位置:

mv /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/javaexec
nano /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java
   (see below for file contents)
chmod +x #!/bin/bash -e

这确保了java对 的每次调用都指向我的脚本,该脚本将使用正确的参数调用可执行文件。之后,我对 做了类似的可怕事情javac。我的脚本内容:

#!/bin/bash -e
line=""
for i in $*
do
  if [[ "$i" == *Xmx* ]]; then
    echo "Seen -Xmx and removed"
  elif [[ "$i" == *MaxPerm* ]]; then
    echo "Seen -XX:MaxPermSize and removed"
  else
    line="$line $i"
  fi
done
exec="/usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/javaexec -Xms10m -Xmx100m $line"
echo Now executing $exec
$exec

-Xmx它从命令行中删除涉及或类似的每个参数-XX:MaxPermSize,并放入其自己的 -Xms 和 -Xmx 限制。

现在当我启动 Tomcat 时,它仍然会失败,但最终,JVM 启动了,执行了一些操作,然后退出并显示一条有意义的消息。虽然没有真正的成功,但它让我更加满意,因为从那时起,我知道该怎么做了。虽然 Tomcat 仍然无法运行,但它有一个很好的副作用:

现在我终于可以在命令行或脚本中调用javajavac,而且它们不会崩溃,这在以前是不可能的根本! 他们只是跑步!嘿,我觉得自己是文字之王,我终于让 Java 在一台拥有 44GB 内存的机器上运行,而不会抱怨内存不足。这确实是计算机历史上伟大的一天!

答案4

我曾经遇到过类似的问题。你可以尝试使用以下方式启动 Java

vm.overcommit_memory = 1 复制代码

在 /etc/sysctl.conf 中设置。或者简单地 echo"1" > /proc/sys/vm/overcommit_memory

或者使用 overcommit_memory、overcommit_ratio http://www.redhat.com/magazine/001nov04/features/vm/

相关内容