运行bazel build时发生java.lang.OutOfMemoryError
我一直在尝试在MAC电脑上的Ubuntu虚拟机上安装ONOS控制器,步骤如下: 但是,执行以下命令后,生成过程不成功:运行bazel build时发生java.lang.OutOfMemoryError,build,controller,jvm,bazel,onos,Build,Controller,Jvm,Bazel,Onos,我一直在尝试在MAC电脑上的Ubuntu虚拟机上安装ONOS控制器,步骤如下: 但是,执行以下命令后,生成过程不成功: ~/onos$ bazel build onos 上述命令输出以下内容: Starting local Bazel server and connecting to it... INFO: Analysed target //:onos (759 packages loaded, 12923 targets configured). INFO: Found 1 target.
~/onos$ bazel build onos
上述命令输出以下内容:
Starting local Bazel server and connecting to it...
INFO: Analysed target //:onos (759 packages loaded, 12923 targets configured).
INFO: Found 1 target...
.
.
.
enconfig-native; [2,128 / 2,367] //models/openconfig:onos-models-openconfig-native; ERROR: /home/mohamedzidan/onos/models/openconfig/BUILD:11:1: Building models/openconfig/libonos-models-openconfig-native-class.jar (2 source jars) failed (Exit 1)
[2,128 / 2,367] //models/openconfig:onos-models-openconfig-native; An exception has occurred in the compiler (10.0.1). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.OutOfMemoryError: Java heap space
at jdk.compiler/com.sun.tools.javac.util.ArrayUtils.ensureCapacity(ArrayUtils.java:60)
at jdk.compiler/com.sun.tools.javac.util.SharedNameTable.fromUtf(SharedNameTable.java:132)
at jdk.compiler/com.sun.tools.javac.util.Names.fromUtf(Names.java:392)
at jdk.compiler/com.sun.tools.javac.util.ByteBuffer.toName(ByteBuffer.java:159)
at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter$CWSignatureGenerator.toName(ClassWriter.java:320)
at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter$CWSignatureGenerator.access$300(ClassWriter.java:266)
at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.typeSig(ClassWriter.java:335)
at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeMethod(ClassWriter.java:1153)
at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeMethods(ClassWriter.java:1653)
at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeClassFile(ClassWriter.java:1761)
at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeClass(ClassWriter.java:1679)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:743)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1641)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1609)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:959)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:100)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl$$Lambda$97/1225568095.call(Unknown Source)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:142)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:96)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:90)
at com.google.devtools.build.buildjar.javac.BlazeJavacMain.compile(BlazeJavacMain.java:113)
at com.google.devtools.build.buildjar.SimpleJavaLibraryBuilder$$Lambda$70/778731861.invokeJavac(Unknown Source)
at com.google.devtools.build.buildjar.ReducedClasspathJavaLibraryBuilder.compileSources(ReducedClasspathJavaLibraryBuilder.java:57)
at com.google.devtools.build.buildjar.SimpleJavaLibraryBuilder.compileJavaLibrary(SimpleJavaLibraryBuilder.java:116)
at com.google.devtools.build.buildjar.SimpleJavaLibraryBuilder.run(SimpleJavaLibraryBuilder.java:123)
at com.google.devtools.build.buildjar.BazelJavaBuilder.processRequest(BazelJavaBuilder.java:105)
at com.google.devtools.build.buildjar.BazelJavaBuilder.runPersistentWorker(BazelJavaBuilder.java:67)
at com.google.devtools.build.buildjar.BazelJavaBuilder.main(BazelJavaBuilder.java:45)
[2,128 / 2,367] //models/openconfig:onos-models-openconfig-native; Target //:onos failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 1386.685s, Critical Path: 117.31s
INFO: 379 processes: 125 linux-sandbox, 254 worker.
**FAILED: Build did NOT complete successfully**
您的输出显示
java.lang.OutOfMemoryError:java堆空间
。您可以通过以下方式增加javac
的可用内存量:
BAZEL_JAVAC_OPTS="-J-Xms384m -J-Xmx512m"
sudo swapoff -v /swapfile # turn swap file off
sudo swapon --show # verify the swap file is off
free -h # you can also look at this as an
# indication the swap file is off
sudo rm /swapfile # remove the swap file
如果仍然不起作用,请尝试逐步增加-Xmx
的大小。这一问题将在以下会议上进一步讨论:
如果Bazel因以下错误的任何版本而失败,那是因为它在尝试构建时耗尽了堆空间 错误:
java.lang.OutOfMemoryError: Java heap space
我在你粘贴的输出中看到了这个错误。虽然不太为人所知,但一些大型项目和mono Repo可能需要16GB或更多的堆,因此我建议您在Linux构建机器上创建一个32GB~64GB的大规模交换文件(虚拟内存),并让它运行!给它整个东西来建造
注意事项:如果您有标准HDD(旋转硬盘驱动器),这可能会导致构建运行速度比使用物理RAM构建慢几十倍甚至数百倍!这是因为硬盘速度非常慢
BUUUT:如果您有一个2.5英寸或3.5英寸的SSD(固态驱动器),那么它工作正常,或者如果您有一个m.2形状因子SSD,它的性能更好100倍!这是因为m.2形状因子SSD的速度非常快,因此您可以随时使用巨大的交换文件代替RAM,因为这些磁盘运行速度非常快
如果使用顶级内部m.2形状因子SSD,我预计以下使用虚拟内存的构建速度仅比仅使用物理RAM(大小相同)的构建速度慢约2倍。但是,如果您有一个超慢速旋转的HDD,使用内部m.2 SSD上的交换文件需要2小时的同一构建可能需要*多天*或更多时间使用旋转HDD上的交换文件
当然,您的结果可能会有所不同,但更倾向于使用更小的JVM bazel堆(使用更少的虚拟内存),您期望的虚拟内存(交换文件)越慢
sudo fallocate -l 64G /swapfile # create a 64 GB file
sudo chmod 600 /swapfile # set permissions to rw for ONLY the user (root!)
sudo mkswap /swapfile
sudo swapon /swapfile
sudo gedit /etc/fstab # edit the /etc/fstab file to make these changes persistent (load them each boot)
# ADD this line to bottom (w/out the # comment symbol):
# /swapfile swap swap defaults 0 0
sudo swapon --show # verify this new 64GB swap file is now active
cat /proc/sys/vm/swappiness # not required: verify your systems "swappiness" value is 60 or so (range is 0 to 100)
BAZEL_JAVAC_OPTS="-J-Xms384m -J-Xmx512m"
sudo swapoff -v /swapfile # turn swap file off
sudo swapon --show # verify the swap file is off
free -h # you can also look at this as an
# indication the swap file is off
sudo rm /swapfile # remove the swap file
然后,您可以再次按照上面的说明以新的大小重新创建它,或者如果要永久删除它,则需要编辑/etc/fstab文件以删除先前添加到底部的/swapfile swap defaults 0
行--host\u jvm\u args=-Xmx32g
添加到任何bazel
命令中,就在单词bazel
之后。这将最大Java虚拟内存(在本例中称为bazel构建堆)设置为32GB,一旦物理RAM已满,它将进入交换文件。如果您有一个高速SSD驱动器,它在交换时运行得出奇地好,那么根据回购的大小,您最多需要等待几个小时。如果您有一个旧的旋转硬盘,那么使用内部m.2 SSD上的交换文件构建一个需要2小时的回购可能需要几天时间,而使用慢速旋转硬盘上的交换文件构建一个回购可能需要几天时间——特别是如果它是一个外部硬盘而不是内部硬盘
下面是添加此bazel启动选项的完整bazel命令示例,用于构建整个回购:
time bazel --host_jvm_args=-Xmx32g build //...
…而不是这个:
time bazel build //...
添加的time
只是打印出一个更可读的打印输出,显示构建所用的时间(我喜欢它)。只要确保为任何bazel构建命令设置分配给bazel的最大Java虚拟内存,只要在需要时将-host\u jvm\u args=-Xmx32g
(或类似)放在单词bazel
之后即可
请注意,像我们在这里使用-Xmx
那样设置最大堆与像其他人使用-Xms
那样设置默认堆不同。设置最大堆仍然从默认堆开始,但如果需要,允许它增长。通过环境变量显示这两种设置请提供Bazel命令的全部输出。刚刚在我的谷歌硬盘上上传了一个输出截图。关于为什么不成功,Jin有什么想法吗?请将整个输出粘贴到你的问题中。刚刚在问题中添加了输出,Jin我应该在哪里插入上面的行?将其作为一个环境变量输入:
export BAZEL_JAVAC_OPTS=“-J-Xms384m-J-Xmx512m”
。然后再次运行Bazel。