- Home /
How do I get Unity to increase the amount of memory passed on the command line to the jvm when making a build for Android?
Hi everybody!
I'm getting the following exception thrown when make an android build from Unity ( this shows up in my Unity console )
Error building Player: CommandInvokationFailure: Unable to convert classes into dex format. See the Console for details. C:\Program Files\Java\jdk1.8.0_20\bin\java.exe -Xmx1024M -Dcom.android.sdkmanager.toolsdir="C:/adt-bundle-windows-x86-20140702/sdk\tools" -Dfile.encoding=UTF8 -jar "C:/Program Files (x86)/Unity/Data/BuildTargetTools/AndroidPlayer\sdktools.jar" -
stderr[
UNEXPECTED TOP-LEVEL ERROR: java.lang.OutOfMemoryError: GC overhead limit exceeded at com.android.dx.rop.code.RopMethod.calcPredecessors(RopMethod.java:173) at com.android.dx.rop.code.RopMethod.labelToPredecessors(RopMethod.java:94) at com.android.dx.ssa.SsaBasicBlock.newFromRop(SsaBasicBlock.java:157) at com.android.dx.ssa.SsaMethod.convertRopToSsaBlocks(SsaMethod.java:173) at com.android.dx.ssa.SsaMethod.newFromRopMethod(SsaMethod.java:103) at com.android.dx.ssa.SsaConverter.convertToSsaMethod(SsaConverter.java:44) at com.android.dx.ssa.Optimizer.optimize(Optimizer.java:98) at com.android.dx.ssa.Optimizer.optimize(Optimizer.java:72) at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:299) at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:139) at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:94) at com.android.dx.command.dexer.Main.processClass(Main.java:682) at com.android.dx.command.dexer.Main.processFileBytes(Main.java:634) at com.android.dx.command.dexer.Main.access$600(Main.java:78) at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:572) at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284) at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166) at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144) at com.android.dx.command.dexer.Main.processOne(Main.java:596) at com.android.dx.command.dexer.Main.processAllFiles(Main.java:498) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:264) at com.android.dx.command.dexer.Main.run(Main.java:230) at com.android.dx.command.dexer.Main.main(Main.java:199) at com.android.dx.command.Main.main(Main.java:103) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at SDKMain.main(SDKMain.java:129)
As far as I can tell, I need the -Xmx1024M to be something biffer like -Xmx2048. However, I have no idea how to tell Unity to use a bigger number there. I'm using version 4.5.5p2. This just started happening when I added yet another piece of middleware which, unfortunately, I need to include.
Thanks!
Josh
FWIW: I set _JAVA_OPTIONS to -Xmx2048m and that had no effect- I believe the command line param is overriding that
I too have this problem and cannot build my Android app, since adding more 3rd party SD$$anonymous$$s. I have tried your solution, which made perfect sense to me, but now Unity doesn't recognise my new exe as being a valid java version.
Unity reports: Unable to find suitable jdk installation. Please make sure you have a suitable jdk installation. Android development requires at least JD$$anonymous$$ 7 (1.7). The latest JD$$anonymous$$ can be obtained from...
I can't figure out why Unity doesn't recognise it. I've set up as many of the file properties as I can to match the real java.exe. I also considered that Unity might check it using the -version command line parameter. But I tried it and the -version param is simply passed through the stub to the real java.exe, which does report the correct version as required.
Did you experience this problem?
Answer by nsejosh · Nov 06, 2014 at 07:18 PM
If anybody runs into this, I solved this with an evil hack. first, rename your java.exe to java-default.exe. Then replace compile a new java.exe from this c# program. Note it will then use 2048mb to compile ( or change that value down below to use however much you want! )
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
namespace CommandlineInterceptor
{
class Program
{
static void Main( string[] args )
{
//let's get the exe from our assembly location
string exeLocation = typeof( Program ).Assembly.Location;
//now to get the real location, right before the .exe, add -default
exeLocation = exeLocation.Replace( ".exe", "-default.exe" );
//string javaExe = @"C:\Program Files\Java\jdk1.8.0_20\bin\java-default.exe";
string javaExe = exeLocation;
//go through the arguments and replace anything that starts with -Xmx
string arguments = GetFilteredArgString( args );
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = javaExe;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.Arguments = arguments;
//startInfo.RedirectStandardInput = true;
using( Process process = new Process() )
{
process.StartInfo = startInfo;
process.OutputDataReceived += new DataReceivedEventHandler( HandleOutputData );
process.ErrorDataReceived += new DataReceivedEventHandler( HandleErrorData );
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
Stream inputStream = Console.OpenStandardInput();
string allInput = Console.In.ReadToEnd();
process.StandardInput.Write( allInput );
process.WaitForExit();
}
}
private static void HandleOutputData( object inProcess, DataReceivedEventArgs inLine )
{
//send the data to the console, no matter what it is...
Console.Out.WriteLine( inLine.Data );
}
private static void HandleErrorData( object inProcess, DataReceivedEventArgs inLine )
{
//send the data to the console, no matter what it is...
Console.Error.WriteLine( inLine.Data );
}
private static string GetFilteredArgString( string[] inArgs )
{
StringBuilder sb = new StringBuilder();
foreach ( string arg in inArgs )
{
if( arg.Contains( "-Xmx" ) )
{
sb.Append( "-Xmx2048 " );
}
else
{
sb.Append( arg );
sb.Append( " ") ;
}
}
return sb.ToString();
}
}
}
This isn't working for me. Unity says "Unable to find suitable JD$$anonymous$$ installation" after I swap out the exe file.
I also had to modify the original .cs code to actually make it run properly on my machine. The original code hangs on Console.In.ReadToEnd(); because it's waiting for an EOF character. $$anonymous$$y fixed code is here: https://gist.github.com/tayl0r/bd943708358abf64732f
These problems might be because of my OS. I'm on Windows 8.1 using Unity 4.5.5p5
Answer by PlanetTimmy · Nov 25, 2014 at 11:29 AM
By the way, if you're using OSX, the following bash script will also do the job:
#!/bin/bash
# Script to override the memory size for java so that it doesn't barf on large Unity projects
/usr/bin/java.original ${@/Xmx1024M/Xmx2048M}
Save the above file to a file called 'java', then do the following:
chmod 755 java
sudo mv /usr/bin/java /usr/bin/java.original
sudo mv java /usr/bin/java
You Rock! Thanks :)
A small caveat for others with the same issue: Your current java may not be in /usr/bin - pay attention to the commandline in the Unity editor log. $$anonymous$$ine was using the installed JD$$anonymous$$ in
/Library/Java/JavaVirtual$$anonymous$$achines/jdk1.7.0_25.jdk/Contents/Home/bin
If you run into this issue, chances are you will also run into the DEX-65$$anonymous$$ limit, so here's a bit of help:
https://medium.com/@rotxed/dex-skys-the-limit-no-65k-methods-is-28e6cb40cf71
Answer by Stockx · Jan 13, 2015 at 12:22 PM
Hey guys, this has been fixed in Unity 4.6.1p3:
http://unity3d.com/unity/qa/patch-releases
(none) - Android: Increase maximum memory available to Java when building for Android.
Cheers!
Answer by rsodre · Jul 04, 2017 at 04:10 PM
If building system is Gradle...
Build, but check "Export Project"
Add this to build.gradle on the exported project
android {
...
dexOptions {
javaMaxHeapSize "2g"
}
...
}
Copy build,gradle to Assets/Plugins/Android/mainTemplate.gradle
Build APK
Remember to repeat this if you install any other android plugin
Answer by augivision · Mar 28, 2018 at 09:11 PM
I deleted all .webm video files from my project.
I also made sure to transcode any other videos.
Now it builds fine.
Your answer
Follow this Question
Related Questions
PrintScreen with alpha in background 0 Answers
Object Despawns/disappears in Android build of game 1 Answer
Unity can't receive information from Intent *urgent 0 Answers
VR (Camera Fov & GearVR) question ! 0 Answers
How to email highscore through android? 2 Answers