Android Studio编译报错“java.lang.OutOfMemoryError: GC overhead limit exceeded”

本文介绍了解决Android Studio编译时遇到的java.lang.OutOfMemoryError: GCoverheadLimitExceeded错误的方法。该错误通常由于堆内存不足引起。文章提供了两种解决方案:一种是在整个工程中增加配置,另一种是在单元测试时增加配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

GC overhead limt exceed检查是Hotspot VM 1.6定义的一个策略,通过统计GC时间来预测是否要OOM了,提前抛出异常,防止OOM发生。Sun 官方对此的定义是:“并行/并发回收器在GC回收时间过长时会抛出OutOfMemroyError。过长的定义是,超过98%的时间用来做GC并且回收了不到2%的堆内存。用来避免内存过小造成应用不能正常工作。”

简而言之:
当GC为释放很小空间占用大量时间时抛出。一般是因为堆太小。
导致异常的原因:没有足够的内存。

Android Studio编译报错 java.lang.OutOfMemoryError: GC overhead limit exceeded
详细的崩溃信息如下:

UNEXPECTED TOP-LEVEL ERROR:
java.lang.OutOfMemoryError: GC overhead limit exceeded
    at com.android.dx.cf.code.RopperMachine.getSources(RopperMachine.java:665)
    at com.android.dx.cf.code.RopperMachine.run(RopperMachine.java:288)
    at com.android.dx.cf.code.Simulator$SimVisitor.visitLocal(Simulator.java:612)
    at com.android.dx.cf.code.BytecodeArray.parseInstruction(BytecodeArray.java:412)
    at com.android.dx.cf.code.Simulator.simulate(Simulator.java:94)
    at com.android.dx.cf.code.Ropper.processBlock(Ropper.java:782)
    at com.android.dx.cf.code.Ropper.doit(Ropper.java:737)
    at com.android.dx.cf.code.Ropper.convert(Ropper.java:346)
    at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:282)
    at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:139)
    at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:94)
    at com.android.dx.command.dexer.Main.processClass(Main.java:682)
    at com.android.dx.command.dexer.Main.processFileBytes(Main.java:634)
    at com.android.dx.command.dexer.Main.access$600(Main.java:78)
    at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:572)
    at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
    at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
    at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
    at com.android.dx.command.dexer.Main.processOne(Main.java:596)
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:498)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:264)
    at com.android.dx.command.dexer.Main.run(Main.java:230)
    at com.android.dx.command.dexer.Main.main(Main.java:199)
    at com.android.dx.command.Main.main(Main.java:103)

解决方案:

  • 如果在整个工程中生效,则在build.gradle中增加如下配置:
android {
..............
      dexOptions {
            incremental true//打开dex增量编译  这还是一个实验性的功能,但是还是推荐打开试试
            javaMaxHeapSize "4G"//设置允许分配的的最大堆内存
        }
...............
}
  • 如果只在单元测试的时候生效,则在build.gradle中增加如下配置:
android {
..............
    testOptions {
        android.dexOptions {
            incremental true
            javaMaxHeapSize "4G"
        }
    }
...............
}
### Spring Boot 中 `java.lang.OutOfMemoryError: GC overhead limit exceeded` 错误解决方案 当应用程序抛出 `java.lang.OutOfMemoryError: GC overhead limit exceeded` 错误时,表明垃圾回收器花费了过多的时间来尝试释放内存,但只恢复了一小部分可用空间[^1]。对于基于 Spring Boot 的应用而言,调整 JVM 参数是一个有效的解决方法。 #### 调整JVM参数配置 为了防止此类错误的发生,在启动 Spring Boot 应用程序时可以增加堆大小并优化垃圾收集行为: -Xms` 和 `-Xmx` 来指定最小和最大的 Java 堆大小。例如,如果希望给定的应用程序分配至少 512MB 至多 4GB 的内存,则可以在命令行中加入如下选项: ```bash -Xms512m -Xmx4g ``` 这有助于确保有足够的内存供应用程序正常运作而不至于频繁触发垃圾回收操作[^3]。 - **启用并发标记清除 (CMS)** 使用 CMS 收集器能够减少长时间暂停的风险,适合那些对响应时间敏感的服务端应用。可以通过下面的参数开启它: ```bash -XX:+UseConcMarkSweepGC ``` 此外还可以考虑其他更先进的垃圾收集算法如 G1 或 ZGC, 它们提供了更好的性能特性[^2]。 - **降低新生代比例** 适当减小年轻代的比例可以帮助缓解老年代的压力,从而间接改善整体表现。比如将新对象区占总堆容量的比例设为 20% : ```bash -XX:NewRatio=4 ``` 以上措施通常能有效预防因过度消耗 CPU 进行垃圾回收而导致 OOM 错误的情况发生。 #### 修改Spring Boot内置Tomcat配置 针对某些特定场景下即使增加了堆栈也无法解决问题的情形,可能是因为默认情况下 Tomcat 使用的是 BIO 模型而非 NIO/Native IO 方式工作所致。此时建议编辑 application.properties 文件以激活异步 I/O 功能,并相应地提高线程池上限值: ```properties server.tomcat.max-threads=800 server.tomcat.min-spare-threads=50 server.tomcat.accept-count=100 server.tomcat.connection-8 ``` 同时也可以探索是否有必要引入连接池组件(如 HikariCP),以便更好地管理数据库资源访问过程中的瞬态峰值需求[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值