I have written one J2EE web service which was run in Tomcat, this service will call Ant to build one J2ME Polish project. It can be run without problem, aber will got such exception "ProGuard is unable to obfuscate: java.io.IOException: Cannot run
program "java": java.io.IOException: error=12, Cannot allocate memory" after several times' building. This is abvious OutofMemory exception.
Tomcat service was run on CentOS linux, the first thing what i thought is to increase the initial memory of Tomcat.
Edit the catalina config file:
opt/tomcat/bin/catalina.sh (catalina.bat for win)
add such command line:
CATALINA_OPTS="-Xms512m -Xmx512m -XX:MaxPermSize=512m"
(I have also tried this: JAVA_OPTS="$JAVA_OPTS -Xms512M -Xmx512m" , but Tomcat can not be started.)
Anyway, Tomcat now has enough memory.
Continue the testing. Now situation is better, after more than 50 times' building, Ant still threw this exception. Restarted Tomcat can not help solving this problem, memory of Tomcat will increase after each building till this exception occused. Ok, i tried to optimize my code, release every object when finished their life, this only help a little bit. This exception always occured.
No idea now, google............found one article: Outofmemory with Ant and this information:
"If you are compiling with javac task in Apache Ant, set fork attribute
to true, to run javac in a separate process with its own heap size
settings. If fork is set to false, or not set (default is false), javac
will run in the same process as Ant, which has a default maximum heap
size of 64m."
<javac srcdir="${basedir}/src"
destdir="${basedir}/build/classes"
classpath="${project.classpath}"
fork="true"
memoryinitialsize="256m"
memorymaximumsize="256m">
</javac>
This <javac> section will be set under <target>. 64m for Tomcat service is not tiny thing.
Useful information, Ant can be alocated with seperate memory and thread. But J2ME Polish build can not use <javac> element, but it support <compiler> element, which "calls the Java compiler normally with the appropriate classpath as well as bootclasspath for the
current target device. In some cases you might want to adjust the compiler settings, however, so you can use the
nested <compiler> element. Along to all attributes of the standard <javac> task......."
Great! So I add this element under :
<target>
-<j2mepolish>
--<build>
---<compiler fork="yes" memoryinitialsize="128m" memorymaximumsize="128m"/>
and test Tomcat again, after Ant building task, memory of Tomcat increase only a little bit, it is normal, the Ant has used seperated memory for building the Polish task! Tomcat can stay stable now.
With this <compiler> element, we can use other optional arguments such as classpath, sourcepath....