Gradle Application插件run任务读取System.in时堆内存耗尽问题
解决Gradle Run任务处理大标准输入时堆内存耗尽的问题
遇到这种情况确实头疼——直接跑Jar一切正常,用Gradle的run任务就内存爆掉,核心原因其实是Gradle默认会缓存整个标准输入流再传递给你的应用,而不是像直接运行Jar那样让应用直接流式读取。针对这个问题,给你几个可行的解决方案:
方案1:禁用Gradle的标准输入缓存(推荐)
Gradle从较新版本开始提供了enableStandardInputCapture配置项,把它设为false就能让Gradle直接把标准输入流传递给你的应用,避免全部缓存到内存里。修改你的build.gradle中的run块:
apply plugin: 'application' mainClassName = "com.PostgresLogLoader" run { standardInput = System.in enableStandardInputCapture = false // 关键:关闭输入缓存 }
这样配置后,Gradle就不会提前把所有输入内容读进内存,你的应用可以像直接运行Jar时一样逐行处理输入,内存占用会保持稳定。
方案2:增大Gradle Daemon的堆内存
如果你的Gradle版本比较旧,没有enableStandardInputCapture这个选项,可以临时通过增大Gradle守护进程的堆内存来缓解问题。
方式A:通过gradle.properties永久配置
在项目根目录的gradle.properties文件中添加:
org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=512m
这里把堆内存设为2G,你可以根据实际需求调整(比如-Xmx4G)。
方式B:命令行临时指定
每次运行时在命令行添加参数:
mawk -f preprocess-logs.awk logs.txt | ./gradlew run -Dorg.gradle.jvmargs="-Xmx2G"
不过这个方案只是“治标”,本质还是让Gradle能缓存更多输入,不如方案1从根源解决问题。
验证效果
修改配置后重新运行你的命令,观察htop的内存占用:如果是方案1,内存应该会稳定在一个较低的水平(和直接跑Jar时差不多);如果是方案2,内存占用会比之前高,但不会耗尽堆内存。
内容的提问来源于stack exchange,提问作者mistahenry
相关产品推荐
相关产品推荐

