jvm 运行bazel构建时出现java.lang. OutOfMemory错误

wkftcu5l  于 2022-11-07  发布在  Java
关注(0)|答案(2)|浏览(178)

我一直在尝试按照以下链接中的步骤在我的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**
ig9co6j1

ig9co6j11#

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

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

如果仍然不起作用,请尝试逐渐增加-Xmx的大小。此问题将在以下网址进一步讨论:
https://github.com/bazelbuild/bazel/issues/1308

bsxbgnwa

bsxbgnwa2#

摘要

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

java.lang.OutOfMemoryError: Java heap space

...然后执行以下操作:
1.增加RAM * 或 * 虚拟内存交换文件的大小,以模拟拥有更多RAM(有关如何执行此操作的详细信息,请参见下文)。
1.从现在开始,使用bazel命令进行构建,例如,在构建时为Bazel提供更多的堆空间(RAM)。在本例中,我为它提供了最大32 GBRAM:


# 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

我在你粘贴的输出中看到了这个错误。虽然不太为人所知,但一些怪物大小的项目和单库可能需要一个16 GB或更多的堆,所以我建议你在你的Linux构建机器上创建一个巨大的32 GB ~ 64 GB的交换文件(虚拟内存),让它运行!给予它来构建整个东西!

注意事项:如果你有一个标准的HDD(旋转硬盘驱动器),这可能会导致构建运行比使用物理RAM慢几十倍甚至 * 数百倍!这是因为HDD慢得可怕!
BUUUUT:如果您有2.5英寸或3.5英寸SSD(固态驱动器),那么它的工作 ok,或者如果您有 m.2 形状因数SSD,它的工作性能仍然要好100倍!这是因为m.2形状因数SSD的速度快得令人难以置信,所以您可以一直使用巨大的交换文件来代替RAM,因为这些磁盘的运行速度太快了!

  • 如果使用顶级的内部m.2外形规格SSD,我预计以下构建版本使用虚拟内存的速度仅为仅使用物理RAM的2倍左右(相同大小的)来构建。然而,如果你有一个旋转速度超慢的硬盘,在内部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)

1.**要调整交换文件的大小或删除交换文件:**如果您需要调整上面创建的交换文件的大小,您可以这样删除它:

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行。
1.将--host_jvm_args=-Xmx32g添加到任何bazel命令中,紧跟在单词bazel之后。这会将 max Java虚拟内存(在本例中为bazel构建堆)设置为
32 GB**,一旦物理RAM已满,该内存将进入交换文件。* 如果您有一个高速SSD驱动器,该驱动器在交换时运行得非常好,根据存储库的大小,最多需要等待几个小时才能完成构建。* 如果您有一个旧的旋转硬盘,预计一个回购协议,需要2小时的建设与交换文件的内部m.2固态硬盘,可能需要多达 * 几天,也许 * 建立与交换文件的缓慢旋转硬盘-特别是当它是外部而不是内部HDD时。
下面是一个添加了bazel启动选项的完整bazel命令示例,用于构建整个存储库:

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

...而不是这样:

time bazel build //...

这里的time只是打印出一个更可读的打印输出,显示构建所用的时间(我喜欢它)。只要确保在任何需要的时候,通过在单词bazel后面放置--host_jvm_args=-Xmx32g(或类似的)来设置为任何bazel构建命令分配给bazel的最大Java虚拟内存。
请注意,设置 max 堆(就像我们在这里对-Xmx所做的那样)与设置默认堆(就像其他人对-Xms所做的那样)是不同的。设置最大堆仍然从默认堆开始,但如果需要的话,可以让它增长。The other answer显示了通过环境变量设置这两个堆。
搞定了!

参考文献:

1.*****[自己的答案] Ask Ubuntu: How do I increase the size of swapfile without removing it in the terminal?

  1. https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-18-04/
  2. https://serverfault.com/questions/684771/best-way-to-disable-swap-in-linux/684792#684792

另请参阅:

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

相关问题