元空间需要〜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 Xmx gradle.properties
org.gradle.jvmargs=-Xmx5120M
您的 Jenkins 环境对进程可以使用的虚拟内存量 (-v) 有严格的限制。同时,JVM 往往会保留大量的虚拟内存。注意:这不是实际的内存消耗,而只是地址空间的预留,在 64 位系统上实际上是无限的,因此默认情况下 JVM 甚至不会尝试在此类预留中保持谦虚。 Java 进程为 Java 堆和许多其他结构保留虚拟内存:代码缓存、元空间、压缩类空间、线程堆栈等。有关详细信息,请参阅
相关答案1/4 RAM 用于堆;
这里还有一篇
有趣的帖子代替标准 libc 分配器,或使用
MALLOC_ARENA_MAX
限制分配器区域的数量,可以进一步减少虚拟内存消耗。例如,使用以下命令行选项,JVM 保留少于 500 MB 的虚拟内存:
MALLOC_ARENA_MAX=2 java -Xmx100m -XX:ReservedCodeCacheSize=64m -XX:-UseCompressedClassPointers -Xss256k <args>
但是,如果可能的话,我建议改为设置
ulimit -v unlimited
。如上所述,虚拟内存(与物理内存不同)几乎是无限的,因此限制它没有多大意义。