【问题标题】:java.lang.OutOfMemoryError when running bazel build运行 bazel 构建时出现 java.lang.OutOfMemoryError
【发布时间】:2019-03-15 20:32:39
【问题描述】:

我一直在尝试按照以下链接中的步骤在我的 MAC 计算机上的 Ubuntu VM 上安装 ONOS 控制器:Download ONOS code & Build 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**

【问题讨论】:

  • 请提供 Bazel 命令的完整输出。
  • drive.google.com/open?id=1MhU5fliF5CUwsh8HpczKBtkuQClOPyjO 刚刚在我的 Google 驱动器上上传了输出的屏幕截图
  • 任何关于为什么它不成功的想法,Jin
  • 请将整个输出粘贴到您的问题中。
  • 刚刚在问题中添加了输出,Jin

标签: build controller jvm bazel onos


【解决方案1】:

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

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

如果这仍然不起作用,请尝试逐步增加 -Xmx 的大小。此问题将在以下位置进一步讨论:

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

【讨论】:

  • 我应该在哪里插入上面的行吗?辛格
  • 将其导出为环境变量:export BAZEL_JAVAC_OPTS="-J-Xms384m -J-Xmx512m"。然后再次运行 Bazel。
【解决方案2】:

总结

如果 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

我在您粘贴的输出中看到了该错误。虽然鲜为人知,但一些大型项目和单存储库可能需要 16GB 或更多的堆,因此我建议您只需创建一个 32GB~64GB 的大型交换文件(虚拟内存)在您的 Linux 构建机器上并让它运行!全力以赴!

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

BUUUUT:如果您有 2.5" 或 3.5" SSD(固态驱动器),那么它可以工作ok,或者如果你有一个 ,效果会更好 100 倍>m.2 外形 SSD!这是因为 m.2 规格的 SSD 速度非常快,因此您可以一直使用巨大的交换文件代替 RAM,因为这些磁盘运行速度非常快!

如果使用顶级内部 m.2 外形 SSD,我预计以下带有虚拟内存的构建仅比仅使用物理 RAM(相同大小)慢约 2 倍建造。但是,如果您有一个旋转速度极慢的 HDD,则在内部 m.2 SSD 上使用交换文件需要 2 小时的相同构建可能需要 数天 或更长时间旋转硬盘。

当然,您的结果可能会有所不同,但更倾向于使用更小的 JVM bazel 堆(使用更少的虚拟内存),您期望的虚拟内存(交换文件)会越慢。

  1. 将系统的交换文件(虚拟内存)增加到至少 32~64 GB。要添加或删除交换文件,请按照此处的详细说明进行操作:https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-18-04/。更新:在这里使用我自己的说明:How do I increase the size of swapfile without removing it in the terminal?。正如我在那里的回答中解释的那样,我的说明通过使用dd 来避免fallocate 的陷阱。

    简而言之,这里是如何添加交换文件:

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

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

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

    ...而不是这个:

    time bazel build //...
    

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

    请注意,像我们在这里使用-Xmx 那样设置max 堆与像其他人使用-Xms 那样设置默认堆不同。设置最大堆仍然从默认堆开始,但在需要时让它增长。 The other answer 显示通过环境变量进行设置。

完成!

参考资料:

  1. *****[我自己的回答]Ask Ubuntu: How do I increase the size of swapfile without removing it in the terminal?
  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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2019-06-28
    相关资源
    最近更新 更多