jvm 初始化VM时出错-无法分配元空间

x33g5p2x  于 2022-11-07  发布在  其他
关注(0)|答案(1)|浏览(371)

元空间需要约1GB

jenkins@android-build:~$ /var/lib/jenkins/tools/hudson.model.JDK/JDK_8u131/bin/java -version
Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes

以下是用户jenkins的内存限制

jenkins@android-build:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 381421
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) 8000000
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 381421
virtual memory          (kbytes, -v) 4000000
file locks                      (-x) unlimited

尝试复制OutOfMemoryError情况,因此使用ulimit限制内存
运行Java程序还需要多少内存?
我的程序被配置为使用最大4GB的堆

dexOptions {
        javaMaxHeapSize "4g"
        preDexLibraries true
    }

和5GB的Xmxgradle.properties

org.gradle.jvmargs=-Xmx5120M
nqwrtyyt

nqwrtyyt1#

您的Jenkins环境对进程可以使用的虚拟内存(-v)有严格的限制。同时,JVM倾向于保留 * 巨大 * 的虚拟内存。注意:这并不是实际的内存消耗,而只是地址空间的保留,在64位系统上实际上是无限的,因此JVM在默认情况下甚至不会尝试适度地保留地址空间。
Java进程为Java堆和许多其他结构保留虚拟内存:代码缓存、元空间、压缩类空间、线程堆栈等。有关详细信息,请参阅相关答案。
您没有设置任何JVM选项,因此JVM默认保留

  • 1/4 RAM用于堆;
  • 1 GB用于压缩类空间;
  • 240 MB用于代码缓存;
  • 每个线程堆栈1 MB,依此类推。

上面的回答还提到了用于限制这些结构的JVM选项。
这里还有一个interesting post,它描述了减少JVM内存使用的实验。
使用jemalloc代替标准libc分配器,或者使用MALLOC_ARENA_MAX限制分配器区域的数量,可以进一步减少虚拟内存的消耗。
例如,使用以下命令行选项时,JVM保留的虚拟内存将少于500 MB:

MALLOC_ARENA_MAX=2 java -Xmx100m -XX:ReservedCodeCacheSize=64m -XX:-UseCompressedClassPointers -Xss256k <args>

然而,如果可能的话,我建议设置ulimit -v unlimited。如上所述,虚拟内存(不像物理内存)几乎是无穷无尽的,所以限制它没有多大意义。

相关问题