{"id":2396,"date":"2022-08-30T15:24:31","date_gmt":"2022-08-30T15:24:31","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/01\/05\/tomcat-on-virtual-server-jvm-cannot-start-because-44-gb-ram-is-not-enough-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:24:31","modified_gmt":"2022-08-30T15:24:31","slug":"tomcat-on-virtual-server-jvm-cannot-start-because-44-gb-ram-is-not-enough-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/tomcat-on-virtual-server-jvm-cannot-start-because-44-gb-ram-is-not-enough-collection-of-common-programming-errors\/","title":{"rendered":"Tomcat on virtual server: JVM cannot start because 44 GB Ram is not enough ?-Collection of common programming errors"},"content":{"rendered":"<p>I&#8217;m renting a virtual machine, running Ubuntu 9.04. I installed the SUN JDK 6.0 (via apt-get) and Tomcat 6.0.18 (via unzipping).<\/p>\n<h2>General problem with Java (partly solved)<\/h2>\n<p>At first, it was impossible to run a JVM because of memory problems. Even something simple as <code>java -version<\/code> failed with<\/p>\n<pre><code>Error occurred during initialization of VM\nCould not reserve enough space for object heap\nCould not create the Java virtual machine.\n<\/code><\/pre>\n<p>I figured out that even though <code>free<\/code> reported 44 GB of free memory, I was only allowed to use a small fraction of it, something like 284 MB per allocation. Running <code>java -Xms10m -Xmx256m -version<\/code> works fine, but I don&#8217;t want to change every script that invokes java.<\/p>\n<p>Also I read about the <code>JAVA_OPTS<\/code> environment variable, which is honored by many apps. I&#8217;ve set this to <code>\"-Xms10m -Xmx256m\"<\/code><\/p>\n<h2>Problem with Tomcat<\/h2>\n<p>The tomcat startup script <code>catalina.sh<\/code> also uses <code>JAVA_OPTS<\/code>. But event though, I still get the three error lines mentioned above, readable in <code>logs\/catalina.out<\/code>. I know that JAVA_OPTS is used, because when I put nonsense into that variable, I see the consequences in <code>logs\/catalina.out<\/code>.<\/p>\n<p>It seems like Tomcat also wants to start javac, which needs the options prefixed with <code>-J<\/code> like <code>-J-Xms10m -J-Xmx256m<\/code> instead. But I&#8217;m not sure if this is related to the problem, because there is no more output than those three lines.<\/p>\n<p>I&#8217;m starting Tomcat via <code>bin\/startup.sh<\/code> which in turn calls <code>bin\/catalina.sh<\/code>. I know there is also the possibilty to start it via <code>jsrv<\/code>, but I cannot do this, because the make \/ configure process for <code>jsrv<\/code> also wants to call <code>javac<\/code> which fails with the well known three line error message mentioned above.<\/p>\n<p>Now I&#8217;d be interested in two possible kinds of solution:<\/p>\n<ul>\n<li>how can I make Java <em>just work<\/em> on my virtual host, no matter who calls <code>java<\/code> or <code>javac<\/code> and no matter how he calls it?<\/li>\n<li>if this is impossible, how can I adjust Tomcat to just run?<\/li>\n<\/ul>\n<p>PS: Please note that I only have control over the virtual machine, but no control and only limited knowledge over\/about the surrounding physical machine.<\/p>\n<p>PPS: <em>Sorry for the noobish title of this question, but I felt that the original, well written title did not attract enough readers, so I thought this might help \ud83d\ude09 It actually helped, as I got 0 views in the first hour, but 8 views in the hour after the change. Strange world.<\/em><\/p>\n<p>Edit: this is the output of <code>ulimit -a<\/code>:<\/p>\n<pre><code>core file size          (blocks, -c) 0\ndata seg size           (kbytes, -d) unlimited\nscheduling priority             (-e) 20\nfile size               (blocks, -f) unlimited\npending signals                 (-i) 16382\nmax locked memory       (kbytes, -l) 64\nmax memory size         (kbytes, -m) unlimited\nopen files                      (-n) 1024\npipe size            (512 bytes, -p) 8\nPOSIX message queues     (bytes, -q) 819200\nreal-time priority              (-r) 0\nstack size              (kbytes, -s) 8192\ncpu time               (seconds, -t) unlimited\nmax user processes              (-u) unlimited\nvirtual memory          (kbytes, -v) unlimited\nfile locks                      (-x) unlimited\n<\/code><\/pre>\n<ol>\n<li>\n<p><code>javac<\/code> generally spawns a separate process which <em>should<\/em> fall underneath different process rules.<\/p>\n<p><code>-J<\/code> options are for passing args via a wrapper\/launcher to the JVM, I&#8217;ve not seen this on Tomcat.<\/p>\n<p>Find out where the -Xmx is coming from:<\/p>\n<p><code>find \/your\/install\/dir\/with\/tomcat |xargs grep '-Xmx'<\/code><\/p>\n<\/li>\n<li>\n<p>Try running <code>ulimit -v unlimited<\/code> before starting tomcat. If this works, you can probably add this to one or both of the startup scripts, or in <code>\/etc\/profile<\/code>, <code>~\/.bashrc<\/code> or some other shell profile script.<\/p>\n<\/li>\n<li>\n<p>In lack of alternatives I tried a dirty hack: replacing <code>java<\/code> and <code>javac<\/code> by shell scripts which ensure that the proper arguments are passed and allow me to see the exact parameter list. Since this in already an attempt at a very specific solution, and not part of the question, I feld like putting it into an answer.<\/p>\n<p>I searched for all occurences of <code>java<\/code> in my filesystem. There were way to many, because I has several JREs and JDKs on my machine. Even after removing all but one version, there were still many of them. I used <code>find \/ -name \"java\" |xargs file<\/code> to find out which is the <em>real<\/em> one. It told me:<\/p>\n<pre><code>\/var\/lib\/dpkg\/alternatives\/java:               ASCII text\n\/etc\/alternatives\/java:                        symbolic link to `\/usr\/lib\/jvm\/java-6-sun\/jre\/bin\/java'\n\/usr\/share\/java:                               directory\n\/usr\/lib\/jvm\/java-6-sun-1.6.0.16\/bin\/java:     symbolic link to `..\/jre\/bin\/java'\n\/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\n\/usr\/bin\/java:                                 symbolic link to `\/etc\/alternatives\/java'\n<\/code><\/pre>\n<p>So I knew that <code>\/usr\/lib\/jvm\/java-6-sun-1.6.0.16\/jre\/bin\/java<\/code> was the executable. I renamed it to <code>javaexec<\/code> and placed a shell script at it&#8217;s old location:<\/p>\n<pre><code>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\nnano \/usr\/lib\/jvm\/java-6-sun-1.6.0.16\/jre\/bin\/java\n   (see below for file contents)\nchmod +x #!\/bin\/bash -e\n<\/code><\/pre>\n<p>This ensures that every call to <code>java<\/code> in the end points to my script, which will call the executable with the right parameters. After that, I did similar terrible things to <code>javac<\/code>. The contents of my script:<\/p>\n<pre><code>#!\/bin\/bash -e\nline=\"\"\nfor i in $*\ndo\n  if [[ \"$i\" == *Xmx* ]]; then\n    echo \"Seen -Xmx and removed\"\n  elif [[ \"$i\" == *MaxPerm* ]]; then\n    echo \"Seen -XX:MaxPermSize and removed\"\n  else\n    line=\"$line $i\"\n  fi\ndone\nexec=\"\/usr\/lib\/jvm\/java-6-sun-1.6.0.16\/jre\/bin\/javaexec -Xms10m -Xmx100m $line\"\necho Now executing $exec\n$exec\n<\/code><\/pre>\n<p>It removes each and every parameter from the command line that involves <code>-Xmx<\/code> or something like <code>-XX:MaxPermSize<\/code> and puts in its own -Xms and -Xmx limits.<\/p>\n<p>When I now start Tomcat, it still fails, but finally, the JVM starts up, does something, and then exits with a meaningful message. No reel success, but it leaves me a lot more satisfied, since from there on, I know what to do. While Tomcat still doesn&#8217;t run, it has a nice side effect:<\/p>\n<p><em>Now I can finally call <code>java<\/code> or <code>javac<\/code> on the command line or from a script, and they do not crash, which before was not possible <strong>at all<\/strong>! They just <strong>run<\/strong>! Hey, I feel like the king of the word, I finally got java to run on a machine with 44GB of Ram without complaing about insufficient memory. This is a great day in the history of computing, indeed!<\/em><\/p>\n<\/li>\n<li>\n<p>You could also check the java vms that you have installed. Make sure, it&#8217;s not the gcj environment that&#8217;s giving you problems.<\/p>\n<p>try<\/p>\n<pre><code>update-java-alternatives -l\n<\/code><\/pre>\n<p>to see if sun-java6 is your default. Drop &#8220;-l&#8221; to see the other options for this command &#8211; e.g. how to change the default.<\/p>\n<p>If I remember correctly, all java-problems I had on ubuntu had their root in gcj being the default (it might have come in as some dependency prior to sun-java6). If I don&#8217;t remember correctly, it&#8217;s at least the majority of the problems.<\/p>\n<p>Last but not least (and only related to your question): You can put a file named &#8220;setenv.sh&#8221; into tomcat&#8217;s bin directory. This file is not there, but will be read on startup if it can be found. You can make all of your changes here in order to refer to them later. The only minor drawback is, that they&#8217;ll be read on startup as well as on shutdown.<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2014-01-05 22:45:13. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>I&#8217;m renting a virtual machine, running Ubuntu 9.04. I installed the SUN JDK 6.0 (via apt-get) and Tomcat 6.0.18 (via unzipping). General problem with Java (partly solved) At first, it was impossible to run a JVM because of memory problems. Even something simple as java -version failed with Error occurred during initialization of VM Could [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2396","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2396","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=2396"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2396\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=2396"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=2396"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=2396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}