1

我一直在尝试按照以下链接中的步骤在我的 MAC 计算机上的 Ubuntu VM 上安装 ONOS 控制器:下载 ONOS 代码并构建 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...
.
.
.
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**
4

2 回答 2

1

概括

如果 bazel 在构建时内存不足,您会看到以下错误:

java.lang.OutOfMemoryError: Java heap space

...然后这样做:

  1. 增加您的 RAM虚拟内存交换文件大小,以模拟拥有更多 RAM(有关如何执行此操作的详细信息如下)。
  2. 从现在开始,使用这个 bazel 命令构建,例如,在构建时给 Bazel 更多的堆空间 (RAM)。在这种情况下,我给它32GB 的最大RAM:
    # Do this to give Bazel up to 32GB of RAM wile building
    time bazel --host_jvm_args=-Xmx32g build //...
    
    # ...instead of doing this
    time bazel build //...
    

细节

如果 Bazel 因以下错误的任何版本而失败,那是因为它在尝试构建时用尽了堆空间。

示例错误:

java.lang.OutOfMemoryError: Java heap space

我在您粘贴的输出中看到了该错误。虽然鲜为人知,但一些怪物大小的项目和 mono-repos 可能需要16GB 或更多的堆,所以我建议你在 Linux 构建机器上创建一个 32GB~64GB 的大型交换文件(虚拟内存)并让它与它一起运行!给它整个构建!

注意:如果您有标准 HDD(旋转硬盘驱动器),这可能会导致构建运行速度比使用物理 RAM 构建数十甚至数百倍!这是因为硬盘驱动器非常慢!

BUUUUT:如果您有 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 堆(以使用更少的虚拟内存),您期望虚拟内存(交换文件)的速度越慢。

  1. 将系统的交换文件(虚拟内存)增加到至少 32~64 GB。要添加或删除交换文件,请按照此处的详细说明进行操作:https ://linuxize.com/post/how-to-add-swap-space-on-ubuntu-18-04/ 。更新:在这里使用我自己的说明:如何增加交换文件的大小而不在终端中删除它?. 正如我在那里的回答中解释的那样,我的说明避免了fallocate使用dd代替的陷阱。

    简而言之,这是添加交换文件的方法

    sudo dd if=/dev/zero of=/swapfile count=64 bs=1G # Create a 64 GiB file
    sudo mkswap /swapfile           # turn this new file into swap space
    sudo chmod 0600 /swapfile       # only let root read from/write to it, 
                                    # for security
    sudo swapon /swapfile           # enable it
    swapon --show                   # verify this new 64GB swap file is 
                                    # now active
    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 none swap sw 0 0
    cat /proc/sys/vm/swappiness     # not required: verify your systems 
                                    # "swappiness" value is 60 or so (range 
                                    # is 0 to 100)
    
  2. 调整或删除你的交换文件:如果你需要调整你刚刚在上面制作的交换文件的大小,你可以像这样删除它:

    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 none swap sw 0 0之前添加到它底部的行。

  3. 添加--host_jvm_args=-Xmx32g到任何bazel命令,就在单词之后bazel。这会将最大Java 虚拟内存或本例中的 bazel 构建堆设置为32GB,一旦您的物理 RAM 已满,它将进入您的交换文件。如果你有一个高速 SSD 驱动器,它可以通过交换运行得非常好,预计最多等待几个小时才能完成构建,具体取决于 repo 大小。如果您有一个旧的旋转 HDD,预计需要 2 小时才能在内部 m.2 SSD 上构建交换文件的 repo 可能需要长达几天的时间才能在慢速旋转 HDD 上构建交换文件 - 特别是如果它是外部而不是内部硬盘。

    这是添加了此 bazel 启动选项的完整 bazel 命令示例,用于构建整个 repo:

    time bazel --host_jvm_args=-Xmx32g build //...
    

    ...而不是这个:

    time bazel build //...
    

    那里的time添加只是打印出一个更具可读性的打印输出,说明构建花费了多长时间(我喜欢它)。只要确保为任何 bazel 构建命令设置分配给 bazel 的最大 Java 虚拟内存,只要在需要时--host_jvm_args=-Xmx32g在单词后面加上(或类似的) 。bazel

    请注意,像我们在这里所做的那样设置最大-Xmx堆与像其他人那样设置默认堆不同-Xms。设置最大堆仍然从默认堆开始,但在需要时让它增长。另一个答案显示通过环境变量进行设置。

完毕!

参考:

  1. *****[我自己的答案]问 Ubuntu:如何增加交换文件的大小而不在终端中删除它?
  2. https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-18-04/
  3. https://serverfault.com/questions/684771/best-way-to-disable-swap-in-linux/684792#684792

也可以看看:

  1. https://github.com/bazelbuild/bazel/issues/1308
于 2020-03-06T22:57:37.230 回答
1

您的输出显示java.lang.OutOfMemoryError: Java heap space. 您可以通过以下方式增加可用的内存量javac

BAZEL_JAVAC_OPTS="-J-Xms384m -J-Xmx512m"

如果这仍然不起作用,请尝试逐步增加-Xmx. 这个问题在以下位置进一步讨论:

https://github.com/bazelbuild/bazel/issues/1308

于 2019-03-16T19:25:18.377 回答