温馨提示×

Ubuntu Java编译内存不足解决

小樊
39
2026-01-03 02:51:50
栏目: 编程语言

Ubuntu下Java编译内存不足的排查与解决

一、快速判断与定位

  • 先看系统资源:使用命令查看内存与交换分区使用率,确认是否物理内存或Swap不足。命令:free -h。重点关注availableSwap字段。若Swap为0或接近用尽,极易触发OOM或构建中断。
  • 识别构建工具报错特征:
    • ninja failed: exit status 137 常见于被OOM Killer终止(内存/交换不足)。
    • java.lang.OutOfMemoryError: GC overhead limit exceeded 多为JVM堆不足或并行任务过多。
    • OpenJDK报错 error=‘Not enough space’ (errno=12) 常见于内存申请失败(物理内存+Swap不足)。
  • 检查用户资源限制:命令:ulimit -a,关注max memory sizevirtual memory等是否过小。
  • 若是Android AOSP全量编译,还需区分是javac阶段还是Jack/Dx阶段的内存瓶颈,以便采用对应参数调整。

二、通用解决方案(按优先级执行)

  • 增加或扩大Swap(最快速缓解OOM/Killer)
    • 查看当前Swap:free -hswapon -s
    • 创建并启用新Swap(示例新增16G):
      sudo fallocate -l 16G /swapfile
      sudo chmod 600 /swapfile
      sudo mkswap /swapfile
      sudo swapon /swapfile
      echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
      
    • 再次检查:free -h。注意:Swap能缓解但会显著降低编译速度,SSD更合适。
  • 调整JVM堆大小(按工具设置)
    • 通用Java应用/构建:设置环境变量(示例将最大堆设为4G
      echo 'export JAVA_OPTS="-Xms2g -Xmx4g"' >> ~/.bashrc
      source ~/.bashrc
      
    • Gradle项目:在gradle.properties中设置
      org.gradle.jvmargs=-Xmx4g
      
    • Maven项目:在MAVEN_OPTS中设置
      export MAVEN_OPTS="-Xms2g -Xmx4g"
      
    • 提示:堆上限不应超过物理内存的70%~80%,并为系统和其他进程留出余量。
  • 放宽系统资源限制
    • 临时放宽(当前会话):ulimit -v unlimited;必要时也可放宽ulimit -m unlimited
    • 永久放宽需编辑系统限制配置(/etc/security/limits.conf),并重新登录生效。
  • 降低并行度(减少瞬时内存峰值)
    • 降低Gradle并行编译:./gradlew assembleDebug --max-workers 2
    • 降低Maven并行编译:-T 2C(按CPU核心数合理设置)。

三、Android AOSP场景的专项处理

  • 调整Soong javac堆(AOSP 10/11等)
    • 方式一:设置环境变量(示例4G
      export MAVEN_OPTS="-Xms4g -Xmx4g"
      
      修改后建议清理并重拉构建状态:make clobber 或删除out/ 再编译。
    • 方式二:直接修改源码配置
      编辑文件:build/soong/java/config/config.go
      将:pctx.StaticVariable(“JavacHeapSize”, “2048M”)
      改为:pctx.StaticVariable(“JavacHeapSize”, “4096M”)
      生效验证:在out/soong/build.ninja中搜索JavacHeapSize是否为新值。
  • Jack编译器内存(旧版AOSP使用Jack)
    • 设置JVM参数并重启Jack Server:
      export JACK_SERVER_VM_ARGUMENTS="-Xmx4g -Dfile.encoding=UTF-8 -XX:+TieredCompilation"
      out/host/linux-x86/bin/jack-admin kill-server
      out/host/linux-x86/bin/jack-admin start-server
      
    • 或在prebuilts/sdk/tools/jack-admin中同步修改JACK_SERVER_VM_ARGUMENTSJACK_SERVER_COMMAND,加入**-Xmx4g**。
  • Dex阶段内存不足(GC overhead / errno=12)
    • 适当降低并行Dex任务数(如设置**-j**),或先单独对失败模块用更大堆的dx.jar执行dex,再继续全量编译(示例):
      java -Xms2g -Xmx4g -jar prebuilts/sdk/tools/dx.jar --dex --output=out/.../classes.dex in.jar
      
    • 若仍报errno=12,优先增大Swap(见上文)。

四、配置生效验证与常见坑

  • 验证配置是否生效
    • Soong javac堆:检查out/soong/build.ninja中的JavacHeapSize
    • Gradle/Maven:构建日志中查看JVM参数(如**-Xmx**)。
    • Jack:执行out/host/linux-x86/bin/jack-admin show-config查看JACK_SERVER_VM_ARGUMENTS
  • 常见坑与规避
    • 修改AOSP相关配置后未清理out/,导致旧参数残留。
    • 虚拟机未启用或分配足够内存,或未配置Swap,构建极易被OOM Killer终止。
    • 并行度过高导致瞬时内存峰值超限,适当降低**-j或Gradle的–max-workers**。
    • 32位JDK或32位系统构建大项目,地址空间受限,建议使用64位JDK/系统

0